Vmware PowerCLI finding VM and Datastore

Posted Posted in Vmware

If you are looking for a VM datastore with Vmware PowerCLI below is a very usefull code to check :

get-vm | select name , @{N="Datastore";E={[string]::Join(',',(Get-Datastore -Id $_.DatastoreIdList | Select -ExpandProperty Name))}}

This is going to show you all the VMs and their datastore , but you can also put name of a VM in front of get-vm command.

Recover passwords in Microsoft active directory Group policy object

Posted Posted in Microsoft

Recover passwords in Microsoft active directory  Group policy object

Becarefull about putting passwords in Microsoft group policy

I can remember the old days that we use to use scripts for changing local administrator account password on all domain members PCs or adding a user by scripts, it was a simple batch file with the net user command but after a while Microsoft came out with the preferences in the group policy and we were happy with that how easily we can add a new user or update one and dealing with the password stuff!!  yup all of them are really good and the second one is easy to use but don’t forget security! putting passwords in group policy is dangerous this is the thing that I always mention in the whole of my professional life in IT industry and still I can see it among different people, you know what people do not pay attention to the alert! although Microsoft removed the ability to deal with password in the preferences ,but even in the old days when you wanted to configure the password stuff in the preferences there was an alert mentioning that this is a security vulnerability,

in this post I am going to show you some information gathering from different places about how insecure the passwords are in the group policy even when they are hashed.

Every IT pro should know that all authenticated users have read-only access to all the object in active directory domain environment so all the standard users can see the Group policy objects (GPO) in the active directory as you know they are located in \\domain-name\sysvol  and also if a  user can install the remote server administration tools (RSAT) on their computers , they can see the GPOs from group policy management console GPMC!

So i know that you are thinking of passwords in GPOs ! yes every users in the domian can read the passwords! yup but maybe they are encrypted , the answer is yes and no 🙂 we should break this methodologies into 2 categories :

1-If you configure a batch file and want to apply it as a script from GPO, definately the password is in the clear text and every one inside your domian can see that .

2-If you use the preferences , when you follow the GPO in the SYSVOL folder you’ll see the password is encrypted in a XML file some thing like this :


<?xml version=”1.0″ encoding=”utf-8″?>
<Groups clsid=”{3125E937-EB16-4b4c-9934-544FC6D24D26}”>
<User clsid=”{DF5F1855-51E5-4d24-8B1A-D9BDE98BA1D1}” name=”LocalTestUser” image=”0″ changed=”2013-07-04 00:07:13″ uid=”{47F24835-4B58-4C48-A749-5747EAC84669}”>
<Properties action=”C” fullName=”” description=”” cpassword=”sFWOJZOU7bJwICaqvmd+KAEN0o4RcpxxMLWnK7s7zgNR+JiJwoSa+DLU3kAIdXc1WW5NKrIjIe9MIdBuJHvqFgbcNS873bDK2nbQBqpydkjsbsPXV0HRPpQ96phie6N9tn4NF3KYyswokkDnj8gvuyZBXqoG94ML8/jhe37eHJiZGyi5IBoPuCfKpurj2″ changeLogon=”0″ noChange=”0″ neverExpires=”0″ acctDisabled=”0″ userName=”LocalTestUser”/>
</User>
</Groups>

So there is a password filed and you can see the password is hashed, yup but there is a minor problem with this method of encryption and the problem is, the private key for this password encryption is publicly announced by Microsft in MSDN: https://msdn.microsoft.com/en-us/library/cc422924.aspx

So when we have the cipher text(cpassword) that encrypted by public key , then we can decrypt it by the private key which is available in the MSDN , yes pretty simple definitely we need some code here but if you search on the internet you can probably find something I am going to share one of them here :

open notepad , copy and paste the below code into it and save it as Get-GPPPassword.ps1 name


function Get-GPPPassword {

    
    [CmdletBinding()]
    Param ()
    
    #Some XML issues between versions
    Set-StrictMode -Version 2
    
    #define helper function that decodes and decrypts password
    function Get-DecryptedCpassword {
        [CmdletBinding()]
        Param (
            [string] $Cpassword 
        )

        try {
            #Append appropriate padding based on string length  
            $Mod = ($Cpassword.length % 4)
            
            switch ($Mod) {
            '1' {$Cpassword = $Cpassword.Substring(0,$Cpassword.Length -1)}
            '2' {$Cpassword += ('=' * (4 - $Mod))}
            '3' {$Cpassword += ('=' * (4 - $Mod))}
            }

            $Base64Decoded = [Convert]::FromBase64String($Cpassword)
            
            #Create a new AES .NET Crypto Object
            $AesObject = New-Object System.Security.Cryptography.AesCryptoServiceProvider
            [Byte[]] $AesKey = @(0x4e,0x99,0x06,0xe8,0xfc,0xb6,0x6c,0xc9,0xfa,0xf4,0x93,0x10,0x62,0x0f,0xfe,0xe8,
                                 0xf4,0x96,0xe8,0x06,0xcc,0x05,0x79,0x90,0x20,0x9b,0x09,0xa4,0x33,0xb6,0x6c,0x1b)
            
            #Set IV to all nulls to prevent dynamic generation of IV value
            $AesIV = New-Object Byte[]($AesObject.IV.Length) 
            $AesObject.IV = $AesIV
            $AesObject.Key = $AesKey
            $DecryptorObject = $AesObject.CreateDecryptor() 
            [Byte[]] $OutBlock = $DecryptorObject.TransformFinalBlock($Base64Decoded, 0, $Base64Decoded.length)
            
            return [System.Text.UnicodeEncoding]::Unicode.GetString($OutBlock)
        } 
        
        catch {Write-Error $Error[0]}
    }  
    
    #define helper function to parse fields from xml files
    function Get-GPPInnerFields {
    [CmdletBinding()]
        Param (
            $File 
        )
    
        try {
            
            $Filename = Split-Path $File -Leaf
            [xml] $Xml = Get-Content ($File)

            #declare empty arrays
            $Cpassword = @()
            $UserName = @()
            $NewName = @()
            $Changed = @()
            $Password = @()
    
            #check for password field
            if ($Xml.innerxml -like "*cpassword*"){
            
                Write-Verbose "Potential password in $File"
                
                switch ($Filename) {

                    'Groups.xml' {
                        $Cpassword += , $Xml | Select-Xml "/Groups/User/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $UserName += , $Xml | Select-Xml "/Groups/User/Properties/@userName" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $NewName += , $Xml | Select-Xml "/Groups/User/Properties/@newName" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $Changed += , $Xml | Select-Xml "/Groups/User/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                    }
        
                    'Services.xml' {  
                        $Cpassword += , $Xml | Select-Xml "/NTServices/NTService/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $UserName += , $Xml | Select-Xml "/NTServices/NTService/Properties/@accountName" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $Changed += , $Xml | Select-Xml "/NTServices/NTService/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                    }
        
                    'Scheduledtasks.xml' {
                        $Cpassword += , $Xml | Select-Xml "/ScheduledTasks/Task/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $UserName += , $Xml | Select-Xml "/ScheduledTasks/Task/Properties/@runAs" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $Changed += , $Xml | Select-Xml "/ScheduledTasks/Task/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                    }
        
                    'DataSources.xml' { 
                        $Cpassword += , $Xml | Select-Xml "/DataSources/DataSource/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $UserName += , $Xml | Select-Xml "/DataSources/DataSource/Properties/@username" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $Changed += , $Xml | Select-Xml "/DataSources/DataSource/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}                          
                    }
                    
                    'Printers.xml' { 
                        $Cpassword += , $Xml | Select-Xml "/Printers/SharedPrinter/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $UserName += , $Xml | Select-Xml "/Printers/SharedPrinter/Properties/@username" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $Changed += , $Xml | Select-Xml "/Printers/SharedPrinter/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                    }
  
                    'Drives.xml' { 
                        $Cpassword += , $Xml | Select-Xml "/Drives/Drive/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $UserName += , $Xml | Select-Xml "/Drives/Drive/Properties/@username" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $Changed += , $Xml | Select-Xml "/Drives/Drive/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value} 
                    }
                }
           }
                     
           foreach ($Pass in $Cpassword) {
               Write-Verbose "Decrypting $Pass"
               $DecryptedPassword = Get-DecryptedCpassword $Pass
               Write-Verbose "Decrypted a password of $DecryptedPassword"
               #append any new passwords to array
               $Password += , $DecryptedPassword
           }
            
            #put [BLANK] in variables
            if (!($Password)) {$Password = '[BLANK]'}
            if (!($UserName)) {$UserName = '[BLANK]'}
            if (!($Changed)) {$Changed = '[BLANK]'}
            if (!($NewName)) {$NewName = '[BLANK]'}
                  
            #Create custom object to output results
            $ObjectProperties = @{'Passwords' = $Password;
                                  'UserNames' = $UserName;
                                  'Changed' = $Changed;
                                  'NewName' = $NewName;
                                  'File' = $File}
                
            $ResultsObject = New-Object -TypeName PSObject -Property $ObjectProperties
            Write-Verbose "The password is between {} and may be more than one value."
            if ($ResultsObject) {Return $ResultsObject} 
        }

        catch {Write-Error $Error[0]}
    }
    
    try {
        #ensure that machine is domain joined and script is running as a domain account
        if ( ( ((Get-WmiObject Win32_ComputerSystem).partofdomain) -eq $False ) -or ( -not $Env:USERDNSDOMAIN ) ) {
            throw 'Machine is not a domain member or User is not a member of the domain.'
        }
    
        #discover potential files containing passwords ; not complaining in case of denied access to a directory
        Write-Verbose 'Searching the DC. This could take a while.'
        $XMlFiles = Get-ChildItem -Path "\\$Env:USERDNSDOMAIN\SYSVOL" -Recurse -ErrorAction SilentlyContinue -Include 'Groups.xml','Services.xml','Scheduledtasks.xml','DataSources.xml','Printers.xml','Drives.xml'
    
        if ( -not $XMlFiles ) {throw 'No preference files found.'}

        Write-Verbose "Found $($XMLFiles | Measure-Object | Select-Object -ExpandProperty Count) files that could contain passwords."
    
        foreach ($File in $XMLFiles) {
            $Result = (Get-GppInnerFields $File.Fullname)
            Write-Output $Result
        }
    }

    catch {Write-Error $Error[0]}
}

> run as admin the PowerShell in one of the domain members computer and

>check your PowerShell execution policy by Get-ExecutionPolicy  command  the best setting is RemoteSigned 

>if it is not this change it by the set-executionpolicy remotesigned command

> change the directory to the location of Get-GPPassword.ps1 file and

>run import-module .\Get-GPPPassword.ps1

>after that run Get-GPPPassword  without any extension

Voala now excavate the output and you’ll definitely find some useful information 🙂

AWS Backup solution

Posted Posted in AWS

Are you looking for AWS Backup solution ?

Today, Amazon Web Services, Inc. (AWS), announced AWS Backup, a fully-managed, centralized backup service that makes it faster and simpler for customers to back up their data across AWS services and on-premises, helping customers more easily meet their business and regulatory backup compliance requirements. AWS Backup makes protecting storage volumes, databases, and file systems easier by giving customers a single service to configure and audit the AWS resources they backup, automate backup scheduling, set retention policies, and monitor recent backups and restores in one place. To get started with AWS Backup visit: aws.amazon.com/backup.

So just go to the AWS console in the storage Section there is a AWS backup

Remove virbr0 interface from Linux

Posted Posted in Linux

Remove virbr0 interface from your Linux

if you like to have a clean output when you are running ifconfig and avoid having so many unused interfaces, you can read this post for remvoing virtual interfaces

of course, if you are not using any kind of virtualization, follow below steps :

First, open your shell and switch to root  and then run below command  :

Actually, with the first command, we are switching to root !

sudo su –
virsh net-destroy default
virsh net-undefine default
systemctl stop libvirtd.service
systemctl disable libvirtd.service
yum remove qemu-kvm qemu-img virt-manager libvirt libvirt-python libvirt-client virt-install virt-viewer bridge-utils

Linux

Secure your Raspberry Pi with iptables

Posted Posted in Linux

For securing your Raspberry Pi with iptables , if your device has Internet then securing your Raspberry Pi is a must !

First of all i got Raspberry Pi 3 and when I was checking the auth log file, i saw a lot of logins try from different IP addresses 

technically what i did is just ran #sudo tail -f /var/log/auth.log

Below are the commands that you can run to configure iptables and make your Pi more secure :

# Add a log rule to see what kind of traffic we are getting 

sudo iptables -t filter -A INPUT -j LOG

# sudo iptables -L -nv –line  >>> just going to show us the current rules in all the chains (INPUT, FORWARD, OUTPUT) of filter table ( default )

After running this command you can go to /var/log/messages and see what kind of traffic is actually coming to your Linux box and then if its legit you can add an accept rule for it

With this method you can easily identify all the traffics like  source IP address (SRC) and Destination IP (DST) also you can check the Destination port (DPT)  

in the above screenshot , i have a lot of packets for SSH (DPT=22) because i am remotely connected to my Raspbery Pi , if i put a deny any any rule without opening my SSH then i’ll lose my remote connection! 

so that’s why this LOG line is really useful , technically we can check it , add accept rule and when  we are sure that there is no other traffic that must be allowed we then add a deny any any at the bottom of the iptables chain

Well after examining messages log file it’s obvious that we need a rule for SSH, so i am going to add the following :

# sudo iptables -t filter -I INPUT 1 -p tcp -s <SRC address from log file> –dport 22 -j ACCEPT

so basically i am working on filter table (-t filter ) which is the default table and even we can omit it from our command and then i am using (-I ) for insert the rule ! 

if you compare this command with the previous one, i was suing (-A) for appending the rule! since the order of the rules are important and iptables are going to check all the matches from the top to bottom 

then i am going to insert the rest of rules at the top of the chain !

with (-p ) i am mentioning the protocol and (-s ) is the source IP address which you should decide from where you wanna access your Pi and then with (–dport ) i am mentioning destination port 22 for SSH

it’s up to you to add more accept rules for the legit traffic other than that there are couple of rules that i usually suggest to add in order to make sure everything is working smoothely :

# sudo iptables -t filter -I INPUT 1 -i lo -j ACCEPT >>> This is for allow loopback

# sudo iptables -t filter -I INPUT 1 -m state –state ESTABLISHED,RELATED -j ACCEPT >>> For allow all Established and related traffic

so at this stage my iptables rules are as below :

But as you can see we are not denying any traffic at the bottom of the chain we need to add a deny rule after rule 5 to block unneccassry traffic and we can easily achive this with :

# sudo iptables -t filter -A INPUT -j DROP

That’s mostly it , you can also do the same thing for other chains and remove the LOG at the end.

Netapp New Features insight 2018

Posted Posted in Netapp

In this post, I’d like to talk about Netapp New features in insight 2018

First of all , In NetApp’s annual three-day technical training conference, attendees heard more about becoming a data visionary. 

So , Netapp focus was more on Cloud solutions  and one of the new was Kubernetes and Netapp and The stackpoint.io Kubernetes-as-a-service platform combined with NetApp’s Cloud Data Services creates a complete DevOps solution, so customers can focus on innovation, not administration.

So Below is a summary of the new features :

  • Cloud insight
    • With dynamic topology and correlation analysis
    • Identifying abandoned and unused resources to right size
    • Get advanced analytics and machine learning to identify issues before they become critical outages
  • Azure Netapp Files
    • NFS storage right in the Azure portal
    • REST API support, CLI access
  • Cloud Volumes Service for AWS
  • Introducing new HCI Compute Nodes with new switches
  • Ansible module for Netapp
  • Flash-Accelerated object storage for IoT
  • StorageGrid SG6060 Appliance
  • MAX Data
    • Nanoseconds latency using PMEM
    • For latency-sensitive apps and DBs
  • Snapmirror strict synchronous/synchronous
  • MetroCluster Enhancements
    • Maximum distance increased to 700km
    • Application must be able to tolerate up to 10 ms write acknowledgment latency
  • SVM DR  from MetroCluster
  • Netapp ONTAP AI
  • NetApp Data Availability Services (NDAS)

 

consequently :

In a simple sentence, I’d say there is a tremendous amount of work for cloud solutions!

Finally , Make sure that you are in touch with Social media at the bottom of my Homepage