Archive

Posts Tagged ‘windows 2008’

Wireshark: Eliminating NBNS

March 14, 2011 Leave a comment

If you work with wireshark its good to sniff around on all your vlans once and then. You might be surprised what you’ll find. Today I checked some student vlans and found alot of machines that were very “chatty”.  Also with server names that do not exist anymore in the network.

It seems like alot of NBNS packets on the wire. The NetBIOS Name Service (NBNS) translates human-readable names to IP addresses (much like DNS) and in modern networks its not needed anymore. Since we are running a Windows 2008 R2 network with Windows XP SP3 workstations and do NOT have applications that depend on it we are going to eliminate it.

On the workstations

In the advanced properties of the network card you can change the NetBIOS value.

By default its Enabled and controlled via the DHCP scope. Lets disable this value and add an extra option to the DHCP scopes. You need to add option 001 to the scope with a value of 0x2.

On the server side

If you are absolutely sure that you don’t need NetBIOS/WINS and you do not have any applications that rely on it you can elimate NetBIOS by changing the NetBIOS property on the Nics. When completed you can fire up Wireshark again and check if any NBNS traffic is still on the wire.

Powershell : Add student users to AD with an excel file

February 14, 2011 8 comments

Powershell. or powerHell…well sometimes. I think it has got to do with lack of knowledge about this scripting technique. The more I am working with it the more i am starting to love it. Very powerfull commands to do more with less. Since the migration to exchange 2010 and windows 2008 R2 we are discovering the power of powershell. Now I’ve converted some of my scripts from VBS to powershell. In this article I have created a script to add student users to Active Directory while using a Excel xlsx file and NOT using Quest AD commandlets.

####################################################################
#
PowerShell Script for to add STUDENTS users to Active Directory #
#
#
#
Version: 0.2 #
#
#
#
Requirements: #
#
1. Powershell with Exchange 2010 CMDlets #
#
2. Permissions on Exchange 2010 and Active Directory #
#
3. Excel 2007 Installed #
#
4. Excel file with the following Columns and data: #
#
#
#
Column 1 (A) : Last Name #
#
Column 2 (B) : Middle Name (like van, de, or blank) #
#
Column 3 (C) : First Name #
#
Column 4 (D) : Login Name (like 22222) #
#
Column 5 (E) : Class (like 4K1) #
#
Column 6 (F) : Sector (VMBO, HVWO, PRO) #
#
Column 7 (G) : Password #
#
#
#
Changelog: #
#
0.1 First version Richard #
#
0.2 Add user check Richard #
#
#
#
###################################################################

$strExcelFile = "C:\Scripts\students.xlsx"
$strADDomainName = "domainname.local"
$strDC = "servername"
$strExchangeDB = "EX-DB"
$strExchangeSMTP = "@companyname.nl"

$strADUserLogonScriptHVWO = "Hvwo-student.vbs"
$strADUserProfPathHVWO = "\\servername\Profiles$\studentprofileHvwo"
$strADUserOUHVWO = [ADSI] "LDAP://servername.domainname.local:389/OU=Students,OU=Users,OU=HavoVwo,DC=domainname,DC=local"
$strADUserOUHVWOShort = ",OU=Students,OU=Users,OU=HavoVwo,DC=domainname,DC=local"
$strADUserGroupHVWO = [ADSI] "LDAP://servername.domainname.local:389/CN=Students HavoVwo,OU=Students,OU=groups,OU=HavoVwo,DC=domainname,DC=local"

$strADUserLogonScriptPRO = "Pro-student.vbs"
$strADUserProfPathPRO = "\\servername\Profiles$\studentprofilePro"
$strADUserOUPRO = [ADSI] "LDAP://servername.domainname.local:389/OU=Students,OU=Users,OU=Pro,DC=domainname,DC=local"
$strADUserOUPROShort = ",OU=Students,OU=Users,OU=Pro,DC=domainname,DC=local"
$strADUserGroupPRO = [ADSI] "LDAP://servername.domainname.local:389/CN=Students PRO,OU=Students,OU=groups,OU=Pro,DC=domainname,DC=local"

$strADUserLogonScriptVMBO = "Vmbo-student.vbs"
$strADUserProfPathVMBO = "\\servername\Profiles$\studentprofileVmbo"
$strADUserOUVMBO = [ADSI] "LDAP://servername.domainname.local:389/OU=Students,OU=Users,OU=Vmbo,DC=domainname,DC=local"
$strADUserOUVMBOShort = ",OU=Students,OU=Users,OU=Vmbo,DC=domainname,DC=local"
$strADUserGroupVMBO = [ADSI] "LDAP://servername.domainname.local:389/CN=Students VMBO,OU=Students,OU=groups,OU=Vmbo,DC=domainname,DC=local"

####################################################################
#
FUNCTIONS #
#
###################################################################
function addHVWOuser {
#check if user exists
$Status = (Check-ADUser -username $strADUserAlias).Status
If ($Status -eq 1) {Write-Host "User:" $strADUserAlias "allready exists!"}
Else {
#create user with settings
$newUser = $strADUserOUHVWO.Create("user",$CN)
$newUser.put("sAMAccountName", $strADUserAlias)
$newUser.put("GivenName", $strADUserFirstName)
$newUser.put("SN", $strADUserLastName)
$newUser.put("displayName", $strADUserFullName)
$newUser.put("initials", $strADUserInitials)
$newUser.put("description", $strADUserDiscription)
$newUser.put("profilePath", $strADUserProfPathHVWO)
$newUser.put("scriptPath", $strADUserLogonScriptHVWO)
$newUser.put("userPrincipalName", $strADUserPrincipalName)
$newUser.SetInfo()
$newUser.PsBase.Invoke("SetPassword", $strADUserPassword)
$newUser.PsBase.InvokeSet("AccountDisabled", $false)
$newUser.SetInfo()
#Set password never expires
New-Variable ADS_UF_DONT_EXPIRE_PASSWD 0x10000 -Option Constant
[
int]$flag=$newUser.useraccountcontrol[0]
$newUser.useraccountcontrol=$flag -bor $ADS_UF_DONT_EXPIRE_PASSWD
$newUser.SetInfo()
#Set password cannot be changed
set-passwordchange $newUser.distinguishedname -deny
#wait for user to be created
Start-Sleep -Seconds 10
#Add user to AD Group
$strADUserGroupHVWO.add("LDAP://" + $strDC + "." + $strADDomainName + ":389/" + $CN + $strADUserOUHVWOShort)
#create mailbox and configure mailbox settings
Enable-Mailbox -Identity $strADUserFullName -Alias $strADUserAlias -Database $strExchangeDB -PrimarySmtpAddress $strADUserEmailAddress -ActiveSyncMailboxPolicy 'Default' -DomainController $strDC
Set-CASMailbox -Identity
$strADUserFullName -MAPIEnabled $false -POPEnabled $false -ImapEnabled $false –ActiveSyncEnabled $false -DomainController $strDC
Set-Mailbox -Identity
$strADUserFullName -HiddenFromAddressListsEnabled $true -DomainController $strDC
}
}
function addPROuser {
#check if user exists
$Status = (Check-ADUser -username $strADUserAlias).Status
If ($Status -eq 1) {Write-Host "User:" $strADUserAlias "allready exists!"}
Else {
#create user with settings
$newUser = $strADUserOUPRO.Create("user",$CN)
$newUser.put("sAMAccountName", $strADUserAlias)
$newUser.put("GivenName", $strADUserFirstName)
$newUser.put("SN", $strADUserLastName)
$newUser.put("displayName", $strADUserFullName)
$newUser.put("initials", $strADUserInitials)
$newUser.put("description", $strADUserDiscription)
$newUser.put("profilePath", $strADUserProfPathPRO)
$newUser.put("scriptPath", $strADUserLogonScriptPRO)
$newUser.put("userPrincipalName", $strADUserPrincipalName)
$newUser.SetInfo()
$newUser.PsBase.Invoke("SetPassword", $strADUserPassword)
$newUser.PsBase.InvokeSet("AccountDisabled", $false)
$newUser.SetInfo()
#Set password never expires
New-Variable ADS_UF_DONT_EXPIRE_PASSWD 0x10000 -Option Constant
[
int]$flag=$newUser.useraccountcontrol[0]
$newUser.useraccountcontrol=$flag -bor $ADS_UF_DONT_EXPIRE_PASSWD
$newUser.SetInfo()
#Set password cannot be changed
set-passwordchange $newUser.distinguishedname -deny
#wait for user to be created
Start-Sleep -Seconds 10
#Add user to AD Groups
$strADUserGroupPRO.add("LDAP://" + $strDC + "." + $strADDomainName + ":389/" + $CN + $strADUserOUPROShort)
$strADUserGroupVMBO.add("LDAP://" + $strDC + "." + $strADDomainName + ":389/" + $CN + $strADUserOUPROShort)
#create mailbox and configure mailbox settings
Enable-Mailbox -Identity $strADUserFullName -Alias $strADUserAlias -Database $strExchangeDB -PrimarySmtpAddress $strADUserEmailAddress -ActiveSyncMailboxPolicy 'Default' -DomainController $strDC
Set-CASMailbox -Identity
$strADUserFullName -MAPIEnabled $false -POPEnabled $false -ImapEnabled $false –ActiveSyncEnabled $false -DomainController $strDC
Set-Mailbox -Identity
$strADUserFullName -HiddenFromAddressListsEnabled $true -DomainController $strDC
}
}
function addVMBOuser {
#check if user exists
$Status = (Check-ADUser -username $strADUserAlias).Status
If ($Status -eq 1) {Write-Host "User:" $strADUserAlias "allready exists!"}
Else {
#create user with settings
$newUser = $strADUserOUVMBO.Create("user",$CN)
$newUser.put("sAMAccountName", $strADUserAlias)
$newUser.put("GivenName", $strADUserFirstName)
$newUser.put("SN", $strADUserLastName)
$newUser.put("displayName", $strADUserFullName)
$newUser.put("initials", $strADUserAlias)
$newUser.put("description", $strADUserDiscription)
$newUser.put("profilePath", $strADUserProfPathVMBO)
$newUser.put("scriptPath", $strADUserLogonScriptVMBO)
$newUser.put("userPrincipalName", $strADUserPrincipalName)
$newUser.SetInfo()
$newUser.PsBase.Invoke("SetPassword", $strADUserPassword)
$newUser.PsBase.InvokeSet("AccountDisabled", $false)
$newUser.Put("pwdLastSet", 0)
$newUser.SetInfo()
#Set password never expires
New-Variable ADS_UF_DONT_EXPIRE_PASSWD 0x10000 -Option Constant
[
int]$flag=$newUser.useraccountcontrol[0]
$newUser.useraccountcontrol=$flag -bor $ADS_UF_DONT_EXPIRE_PASSWD
$newUser.SetInfo()
#Set password cannot be changed
set-passwordchange $newUser.distinguishedname -deny
#wait for user to be created
Start-Sleep -Seconds 10
#Add user to AD Group
$strADUserGroupVMBO.add("LDAP://" + $strDC + "." + $strADDomainName + ":389/" + $CN + $strADUserOUVMBOShort)
#create mailbox and configure mailbox settings
Enable-Mailbox -Identity $strADUserFullName -Alias $strADUserAlias -Database $strExchangeDB -PrimarySmtpAddress $strADUserEmailAddress -ActiveSyncMailboxPolicy 'Default' -DomainController $strDC
Set-CASMailbox -Identity
$strADUserFullName -MAPIEnabled $false -POPEnabled $false -ImapEnabled $false –ActiveSyncEnabled $false -DomainController $strDC
Set-Mailbox -Identity
$strADUserFullName -HiddenFromAddressListsEnabled $true -DomainController $strDC
}
}
Function Set-PasswordChange {
Param([string]$dn=$(Throw "You must specify a user's DN"),
[
switch]$Deny)
#only run if user distinguishedname was found
[ADSI]$user="LDAP://" + $strDC + "." + $strADDomainName + ":389/" + $dn
[
Guid]$guid="ab721a53-1e2f-11d0-9819-00aa0040529b"
$everyone = [System.Security.Principal.SecurityIdentifier]"S-1-1-0"
$self = [System.Security.Principal.SecurityIdentifier]"S-1-5-10"
$EveryoneDeny = New-Object System.DirectoryServices.ActiveDirectoryAccessRule ($Everyone,"ExtendedRight","Deny",$guid)
$EveryoneAllow = New-Object System.DirectoryServices.ActiveDirectoryAccessRule ($Everyone,"ExtendedRight","Allow",$guid)
$SelfDeny = New-Object System.DirectoryServices.ActiveDirectoryAccessRule ($self,'ExtendedRight','Deny',$guid)
$SelfAllow = New-Object System.DirectoryServices.ActiveDirectoryAccessRule ($self,'ExtendedRight','Allow',$guid)#Pick the right rules depending on whether $perm is set to Allow or Deny
if ($Deny) {
$SelfRule = $SelfDeny
$EveryoneRule = $EveryoneDeny
}
else
{
$SelfRule = $SelfAllow
$EveryoneRule = $EveryoneAllow
}
#The ModifyAccessRuleMethod requires an object to use for its output
New-Variable r
if (!($User.psbase.ObjectSecurity.ModifyAccessRule('Reset',$SelfRule,[ref]$r))) {
Write-Host "Failed to modify access rule for SELF"
Return
}
If (!($User.psbase.ObjectSecurity.ModifyAccessRule('Reset',$EveryoneRule,[ref]$r))) {
Write-Host "Failed to modify access rule for EVERYONE"
Return
}
# changes were made so commit them
$user.psbase.commitchanges()
}
Function Check-ADUser {
#search for user in AD
Param ($Username)
$ADRoot = [ADSI]''
$ADSearch = New-Object System.DirectoryServices.DirectorySearcher($ADRoot)
$SAMAccountName = "$Username"
$ADSearch.Filter = "(&(objectClass=user)(sAMAccountName=$SAMAccountName))"
$Result = $ADSearch.FindAll()
If($Result.Count -eq 0)
{
#Write-Host "No such user on the Server" | Out-Null
$Status = "0"
}
Else
{
#Write-Host "User exist on the Server" | Out-Null
$Status = "1"
}
$Results = New-Object Psobject
$Results | Add-Member Noteproperty Status $Status
Write-Output $Results
}
####################################################################
#
MAIN SCRIPT #
#
###################################################################
#
Open COM object, start Excel, open Excel File with workbook
$objExcel = New-Object -Comobject Excel.Application
$objExcel.Visible = $True
$objExcelWorkbook = $objExcel.Workbooks.Open($strExcelFile)#First Row contains header, so start with row 2
$objExcelCurrentRow = 2#Loop through excel file and add users with specific settings
do
{
$strADUserLastName = $objExcel.Cells.Item($objExcelCurrentRow,1).Value()
$strADUserMiddleName = $objExcel.Cells.Item($objExcelCurrentRow,2).Value()
$strADUserFirstName = $objExcel.Cells.Item($objExcelCurrentRow,3).Value()
#convert System.double to string value (needed because studentname ia a number)
[string] $strADUserAlias = $objExcel.Cells.Item($objExcelCurrentRow,4).Value()
$strADUserClass = $objExcel.Cells.Item($objExcelCurrentRow,5).Value()
$strADUserSector = $objExcel.Cells.Item($objExcelCurrentRow,6).Value()
$strADUserPassword = $objExcel.Cells.Item($objExcelCurrentRow,7).Value()
If ($strADUserMiddleName -eq $Null) {$strADUserFullName = $strADUserLastName + ", " + $strADUserFirstName} Else {$strADUserFullName = $strADUserLastName + ", " + $strADUserMiddleName + ", " + $strADUserFirstName}
$strADUserDiscription = $strADUserSector + " Class " + $strADUserClass + " (" + $strADUserFullName + ")"
$strADUserPrincipalName = $strADUserAlias + "@" + $strADDomainName
$strADUserEmailAddress = $strADUserAlias + $strExchangeSMTP
$strADUserInitials = $strADUserAlias
$CN = "CN=" + $strADUserAlias
If ($strADUserSector -eq "HVWO") {addHVWOuser}
If ($strADUserSector -eq "PRO") {addPROuser}
If ($strADUserSector -eq "VMBO") {addVMBOuser}
$objExcelCurrentRow++
}
until ($strADUserLastName -eq $Null)#Close Excel Workbook and Excel and cleanup with .Net Framework
$objExcelWorkbook.Close()
$objExcel.Quit()
$Null = & {
[
Runtime.Interopservices.Marshal]::ReleaseComObject($objExcel)
[
Runtime.Interopservices.Marshal]::ReleaseComObject($objExcelWorkbook)
}
GC]::Collect()
####################################################################
#
END MAIN SCRIPT #
#
###################################################################

[

I think this code can easily be followed. If any questions arise or if you have usefull additions or comments don’t hesitate to comment.

Wireshark: Determining a SMB and NTLM version in a Windows environment

February 3, 2011 4 comments

The last few days I am playing around with wireshark and I must say I enjoy working with this program. It has saved the day for me a couple of times by giving me information that is only retrieved by looking at packet level. In this article I was looking at SMB and NTLM traffic in a windows environment. I noticed that our XP based network was running NTLMv1 that is considered unsecure. Let’s change this fast !

Intro

NTLM over a Server Message Block (SMB) transport is one of the most common uses of NTLM authentication and encryption. Kerberos Protocol Extensions (KILE) is the preferred authentication method of an SMB session in Windows Server operating system and Windows Client operating systems. However, when a client attempts to authenticate to an SMB server using the KILE protocol and fails, it can attempt to authenticate with NTLM.

The NT LAN Manager (NTLM) Authentication Protocol is used in Microsoft Windows Networks for authentication between clients and servers.  NTLM is used by application protocols to authenticate remote users and, optionally, to provide session security when requested by the application. There are two major variants of the NTLM authentication protocol: the connection-oriented variant and the connectionless variant. Each of these variants has three versions: LM, NTLMv1, and NTLMv2.  In addition to authentication, the NTLM protocol optionally provides for session security—specifically message integrity and confidentiality through signing and sealing functions in NTLM. For more in depth information I urge you to read this Microsoft NTLM documentation. The following picture will show a protocol flow of NTLM and Simple and Protected Generic Security Service Application Program Interface Negotiation Mechanism (SPNEGO) authentication of an SMB session.

Step 1 and 2 – The SMB protocol negotiates protocol-specific options using the SMB_COM_NEGOTIATE request and response messages. The client will send its supported dialects and the server will respond with the highest possible dialect. The following dialect values are possible (older dialects are excluded here):

Step 3 – The client sends an SMB_COM_SESSION_SETUP_ANDX request message. Assuming that NTLM authentication is negotiated, within this message an NTLM NEGOTIATE_MESSAGE is embedded.

Step 4 – The server responds with an SMB_COM_SESSION_SETUP_ANDX response message within which an NTLM CHALLENGE_MESSAGE is embedded. The message includes an 8-byte random number, called a “challenge”, that the server generates and sends in the ServerChallenge field of the message.

Step 5 – The client extracts the ServerChallenge field from the NTLM CHALLENGE_MESSAGE and sends an NTLM AUTHENTICATE_MESSAGE to the server (embedded in an SMB_COM_SESSION_SETUP_ANDX request message). If the challenge and the response prove that the client knows the user’s password, the authentication succeeds and the client’s security context is now established on the server.

Step 6 – The server sends a success message embedded in an SMB_COM_SESSION_SETUP_ANDX response message.

Wiresharking

This article will only show how to find out which SMB and NTLM versions are used on your windows servers and windows clients while using Wireshark. This is very useful to know because it has a great impact on your security. There are many documents on the internet that show that LM and NTLMv1 are insecure these days therefore we need to ensure that these authentication methods are not allowed inside the windows network. Thus we need to ensure that NTLMv2 only is allowed. This behavior can be changed on windows servers and clients at the following registry key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa

REG_DWORD Valuename: lmcompatibilitylevel

The following values can be used:

So you’re actually configuring a minimum security level here. Now let’s take a look which values are used by default per OS type:

We can conclude that if we have an XP client and a windows 2008 R2 server with default settings it will always use NTLMv1. If we use an Windows 7 or Vista client and a windows 2008 R2 server it will use NTLMv2. Lets fire up Wireshark and take a look what’s happening “on the wire”.

Windows XP client and Windows 2008 R2 server (default settings)

In this scenario a Windows XP client (10.0.0.2) tries to connect to a Windows 2008 R2 Server (10.0.0.1) share. Let’s take a look at the SMB negotiate protocol request:

The highest possible dialect that the Windows XP client can speak is NT LM 0.12. Thus SMB v1.0. Let’s take a look how the Windows 2008 R2 server will respond:

The Windows 2008 R2 server responds its capable of SMB v1.0 (NT LM 0.12) and this is used to access the share. Let’s take a look which version of NTLM it uses by looking at the Session setup andX request: NTLMSSP_AUTH packet.

There is no NTMLv2 section here so it is using NTLMv1. Thus insecure !!

Windows 7 client and Windows 2008 R2 server (default settings)

In this scenario a Windows 7 Client (10.0.0.3) tries to connect to a Windows 2008 R2 Server (10.0.0.1) share. Let’s take a look at the SMB negotiate protocol request:

The highest possible dialect that the Windows 7 client can speak is SMB 2.???. Thus SMB v2.0 Wildcard. Let’s take a look how the Windows 2008 R2 server will respond:

The Windows 2008 R2 server responds its capable of 0x02ff (hexadecimal value for SMBv2.0 wildcard). You can also see that the protocol column switches from SMB to SMB2. Now the Windows 7 clients needs to know which SMB2 version will be used for communication. . Let’s take a look at the new SMB2 negotiate protocol request:

The highest possible SMB2 dialect that the Windows 7 client can speak is more specific now. It can use 0x0202 or 0x0210. Thus SMB v2.002 or SMB v2.1. Let’s take a look how the Windows 2008 R2 server will respond:

The Windows 2008 R2 server responds its capable of 0x210 (hexadecimal value for SMBv2.1) and this is used to access the share. Let’s take a look which version of NTLM it uses by looking at the Session setupRequest, NTLMSSP_AUTH packet.

The picture clearly shows that there is an NTLMv2 response.

Is there a quicker way to determine NTLMv1 or NTLMv2 authentication? Yes. We can do this by entering ntlmssp.ntlmv2response into the filter field. Wireshark will filter out ntlmv2 traffic only.

Back to our little problem. We have a network running with XP clients and windows 2008 R2 server with default settings on GPO level. We saw that NTLMv1 will be used for authentication and thus insecure. We need to change this so the XP machines will authenticate by using NTLMv2. We can achieve this by change the Lmcompatibilitylevel value to 5. The best way to achieve this is by placing all Windows XP clients into an OU and configure a computer GPO policy.

Before you change the server side to Lmcompatibilitylevel value 5 you must be absolutely sure that every Windows XP Client uses NTLMv2 or your phone will start ringing very often. You can achieve this by changing the default domain controllers policy or by placing a GPO on an OU with servers. When the server and client side are changed to NTLMv2 you have achieved the highest NTLM authentication possible. Thus the most secure NTLM form possible. This ends my article about Determining a SMB and NTLM version in a windows environment. I hope it’s useful somehow and feel free to comment.

%d bloggers like this: