블로그 이미지
010-9967-0955 보미아빠

카테고리

보미아빠, 석이 (500)
밥벌이 (16)
싸이클 (1)
일상 (1)
Total
Today
Yesterday

달력

« » 2017.10
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

공지사항

최근에 올라온 글

'2017/10/13'에 해당되는 글 1건

  1. 2017.10.13 Powershell - WinNT Provider

http://learningpcs.blogspot.kr/2011/01/powershell-winnt-provider.html




I reimaged my Windows 7 machine and want to make a new account strictly to contain pen testing tools.  Wondering how I could do this the Powershell way I started looking around. Most everything I found related to domain user management, i.e., LDAP and ADSI.  In my case, I was not dealing with AD per se, but, rather the WinNT provider to add a local account.  I stumbled onto this post:
http://www.vistax64.com/powershell/173919-add-built-account-local-group-using-winnt-adsi-provider.html
where Shay Levy added this little nugget:
$group = [ADSI]"WinNT://$env:COMPUTERNAME/Administrators,group"
$group.add("WINNT://NT AUTHORITY/SYSTEM")
I thought okay, great, I've got something to work with.  My next step was MSDN to try and find some higher level info to work with.  This link came up on Google, but, it really didn't get me far:
http://msdn.microsoft.com/en-us/library/aa746534(v=VS.85).aspx
I then searched for [ADSI]"WinNT Powershell and got an old Scripting Guys post that got me messing around in the right direction:
http://blogs.technet.com/b/heyscriptingguy/archive/2008/03/11/how-can-i-use-windows-powershell-to-add-a-domain-user-to-a-local-group.aspx
As is much more eloquently noted in the post, if you try and pass the reference to a variable and run a Get-Member cmdlet against it, you don't get very far.
$group = [ADSI]"WinNT://$env:COMPUTERNAME/Administrato
rs,group"
$group | gm


TypeName: Microsoft.PowerShell.Commands.MemberDefinition

Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Definition Property System.String Definition {get;}
MemberType Property System.Management.Automation.PSMemberTypes MemberType {get;}
Name Property System.String Name {get;}
TypeName Property System.String TypeName {get;}
Now, if you use the PSBase reference, things start to open up a lot:
Likewise, if you go up one level and focus less on a specific group, but, rather, the machine itself, you see a lot of nice things to start playing with:
$machine = [ADSI]"WinNT://$env:COMPUTERNAME"
$machine | gm


TypeName: System.DirectoryServices.DirectoryEntry

Name MemberType Definition
---- ---------- ----------
ConvertDNWithBinaryToString CodeMethod static string ConvertDNWithBinaryToString(psobject deInstance, psobject dnWit...
ConvertLargeIntegerToInt64 CodeMethod static long ConvertLargeIntegerToInt64(psobject deInstance, psobject largeInt...
Division Property System.DirectoryServices.PropertyValueCollection Division {get;set;}
Name Property System.DirectoryServices.PropertyValueCollection Name {get;set;}
OperatingSystem Property System.DirectoryServices.PropertyValueCollection OperatingSystem {get;set;}
OperatingSystemVersion Property System.DirectoryServices.PropertyValueCollection OperatingSystemVersion {get;...
Owner Property System.DirectoryServices.PropertyValueCollection Owner {get;set;}
Processor Property System.DirectoryServices.PropertyValueCollection Processor {get;set;}
ProcessorCount Property System.DirectoryServices.PropertyValueCollection ProcessorCount {get;set;}
Throwing in the PSBase option, I get much more when I run the gm.
$machine.PSBase | gm


TypeName: System.Management.Automation.PSMemberSet

Name MemberType Definition
---- ---------- ----------
Disposed Event System.EventHandler Disposed(System.Object, System.EventArgs)
Close Method System.Void Close()
CommitChanges Method System.Void CommitChanges()
CopyTo Method adsi CopyTo(adsi newParent), adsi CopyTo(adsi newParent, string newName)
CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)
DeleteTree Method System.Void DeleteTree()
Dispose Method System.Void Dispose()
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetLifetimeService Method System.Object GetLifetimeService()
GetType Method type GetType()
InitializeLifetimeService Method System.Object InitializeLifetimeService()
Invoke Method System.Object Invoke(string methodName, Params System.Object[] args)
InvokeGet Method System.Object InvokeGet(string propertyName)
InvokeSet Method System.Void InvokeSet(string propertyName, Params System.Object[] args)
MoveTo Method System.Void MoveTo(adsi newParent), System.Void MoveTo(adsi newParent, string n...
RefreshCache Method System.Void RefreshCache(), System.Void RefreshCache(string[] propertyNames)
Rename Method System.Void Rename(string newName)
ToString Method string ToString()
AuthenticationType Property System.DirectoryServices.AuthenticationTypes AuthenticationType {get;set;}
Children Property System.DirectoryServices.DirectoryEntries Children {get;}
Container Property System.ComponentModel.IContainer Container {get;}
Guid Property System.Guid Guid {get;}
Name Property System.String Name {get;}
NativeGuid Property System.String NativeGuid {get;}
NativeObject Property System.Object NativeObject {get;}
ObjectSecurity Property System.DirectoryServices.ActiveDirectorySecurity ObjectSecurity {get;set;}
Options Property System.DirectoryServices.DirectoryEntryConfiguration Options {get;}
Parent Property System.DirectoryServices.DirectoryEntry Parent {get;}
Password Property System.String Password {set;}
Path Property System.String Path {get;set;}
Properties Property System.DirectoryServices.PropertyCollection Properties {get;}
SchemaClassName Property System.String SchemaClassName {get;}
SchemaEntry Property System.DirectoryServices.DirectoryEntry SchemaEntry {get;}
Site Property System.ComponentModel.ISite Site {get;set;}
UsePropertyCache Property System.Boolean UsePropertyCache {get;set;}
Username Property System.String Username {get;set;}
As I began poking around I found lots of excellent information that would be good for something like the enumeration phase of a pen test, assuming you could get access to a machine via WinNT provider. It's also flat out useful to find out more about your machine. Here is a treasure trove of information:
($user.PSBase.children) | select * -First 1
UserFlags : {66051}
MaxStorage : {-1}
PasswordAge : {48034693}
PasswordExpired : {0}
LoginHours : {255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255}
FullName : {}
Description : {Built-in account for administering the computer/domain}
BadPasswordAttempts : {0}
LastLogin : {7/13/2009 10:53:58 PM}
HomeDirectory : {}
LoginScript : {}
Profile : {}
HomeDirDrive : {}
Parameters : {}
PrimaryGroupID : {513}
Name : {Administrator}
MinPasswordLength : {0}
MaxPasswordAge : {3628800}
MinPasswordAge : {0}
PasswordHistoryLength : {0}
AutoUnlockInterval : {1800}
LockoutObservationInterval : {1800}
MaxBadPasswordsAllowed : {0}
objectSid : {1 5 0 0 0 0 0 5 21 0 0 0 50 63 56 2 145 31 129 81 36 160 45 106 244 1 0 0}
AuthenticationType : Secure
Children : {}
Guid : {D83F1060-1E71-11CF-B1F3-02608C9E7553}
ObjectSecurity :
NativeGuid : {D83F1060-1E71-11CF-B1F3-02608C9E7553}
NativeObject : System.__ComObject
Parent : WinNT://WORKGROUP/MyMachine
Password :
Path : WinNT://WORKGROUP/MyMachine/Administrator
Properties : {UserFlags, MaxStorage, PasswordAge, PasswordExpired...}
SchemaClassName : User
SchemaEntry : System.DirectoryServices.DirectoryEntry
UsePropertyCache : True
Username :
Options :
Site :
Container :
If you don't think this tells you a lot about a given machine, I don't know what to tell you.

Pulling back from the hidden wealth of information just discovered and refocusing on the task at hand, I still needed to know how to add a new local user account.  I dug up another, perfect script:
http://stackoverflow.com/questions/383390/create-local-user-with-powershell-windows-vista
which threw out a function:
function create-account ([string]$accountName = "testuser") { 
$hostname = hostname 
$comp = [adsi] "WinNT://$hostname" 
$user = $comp.Create("User", $accountName) 
$user.SetPassword("Password1") 
$user.SetInfo() 
}
Seeing snippets of references I had already looked at--Create, SetPassword, SetInfo--I figured I would go with this and just get things setup. After thinking it through, however, I decided to add a little functionality and write my own function, mainly to enable the specification of UserFlags. If you have never worked with the UserFlags enumeration it can be referenced here:
http://msdn.microsoft.com/en-us/library/Aa772300
Here is the main segment worth focusing on as outlined in the typedef for this enum:
typedef enum {
ADS_UF_SCRIPT = 1, // 0x1
ADS_UF_ACCOUNTDISABLE = 2, // 0x2
ADS_UF_HOMEDIR_REQUIRED = 8, // 0x8
ADS_UF_LOCKOUT = 16, // 0x10
ADS_UF_PASSWD_NOTREQD = 32, // 0x20
ADS_UF_PASSWD_CANT_CHANGE = 64, // 0x40
ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 128, // 0x80
ADS_UF_TEMP_DUPLICATE_ACCOUNT = 256, // 0x100
ADS_UF_NORMAL_ACCOUNT = 512, // 0x200
ADS_UF_INTERDOMAIN_TRUST_ACCOUNT = 2048, // 0x800
ADS_UF_WORKSTATION_TRUST_ACCOUNT = 4096, // 0x1000
ADS_UF_SERVER_TRUST_ACCOUNT = 8192, // 0x2000
ADS_UF_DONT_EXPIRE_PASSWD = 65536, // 0x10000
ADS_UF_MNS_LOGON_ACCOUNT = 131072, // 0x20000
ADS_UF_SMARTCARD_REQUIRED = 262144, // 0x40000
ADS_UF_TRUSTED_FOR_DELEGATION = 524288, // 0x80000
ADS_UF_NOT_DELEGATED = 1048576, // 0x100000
ADS_UF_USE_DES_KEY_ONLY = 2097152, // 0x200000
ADS_UF_DONT_REQUIRE_PREAUTH = 4194304, // 0x400000
ADS_UF_PASSWORD_EXPIRED = 8388608, // 0x800000
ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 16777216 // 0x1000000
} ADS_USER_FLAG_ENUM;
This script can give you a taste of a few others ways to play with the UserFlags enum and the -bor operator if you want to be more precise in your settings:
http://poshcode.org/685
As noted in this post there is a little usage of the binary comparison operators. You can get more detail (plus some examples) by typing Get-Help about_comparison operators in your shell.

Once I had all this set up I arrived at this script:
function Add-LocalUser
{
param(
[Parameter(Mandatory = $true, Position = 1)]
[String]
$UserName, 
[Parameter(Mandatory = $true, Position = 2)]
[String]
$Password, 
[Parameter(Mandatory = $false, Position = 3)]
[Int32]
$UserFlags,
[Parameter(Mandatory = $false, Position = 4)]
[String]
$ComputerName = $env:COMPUTERNAME
)

$comp = [adsi] "WinNT://$ComputerName"
$user = $comp.Create("User", $UserName)
$user.SetPassword($Password)
if($UserFlags)
{
$user.UserFlags = $UserFlags
}
$user.SetInfo()
}
To use this function I do this: 
Add-LocalUser User P@55w0RD (65536 + 64)
To add the user to a group, I can go back to the boiler plate code from the original Scripting Guys post and put this right where I need it.


Posted by 보미아빠
, |

최근에 달린 댓글

최근에 받은 트랙백

글 보관함