joeware - never stop exploring... :)

Information about joeware mixed with wild and crazy opinions...

1/5/2020

AdFind V01.52.00… It is almost time…

by @ 2:33 pm. Tags:
Filed under tech, updates

Image may contain: meme and text

I have stripped out the debugdebugs and the expiration code as I am thinking at the moment that this will be the last build of V01.52.00 barring any bug reports that are serious enough to deal with… I will use it at work for a week and see if there are any issues and if not it will be the actual release version.

I will not be updating the daily build on the ftp site for this as the beta expiration is stripped out. That being said, the current daily is VERY close to this final version so that is good enough for testing.

SNAGHTML414bd5d8

   joe

Rating 4.00 out of 5

1/4/2020

WHOA!

by @ 11:59 am. Filed under general

Looks like wordpress updated something… Everything has gone cuckoo!

Edit: For some reason the color schemes and some of the displayed stuff is different for a logged in user versus a guest. Trying to sort it out. 🙂

Edit2: This should be all sorted out now, if things look weird, comment here.

Rating 4.33 out of 5

12/28/2019

AdFind V01.52.00…

by @ 12:48 am. Filed under tech, updates

AdFind V01.52.00 is close to release. It went slow because I finally worked on integrating boost::regex functionality into AdFind. Including both match and substitute functionality. The regex components will be considered beta for a few versions as there is a lot to figure out here and how people will use it. Also it isn’t my code, I am just pulling in the boost functionality. It is pretty close to perl regular expressions but not exactly.

If you want to play with the release candidate beta, you can find it at https://www.joeware.net/downloads/beta/rc

List of fixes/updates:

//* V01.52.00  2019.0514      o 05/14   Convert to VS 2019                  *
//*                                     Add 2K19 RootDSE decodes            *
//*                                     Change all rootdse to have nopaging *
//*                                     Alias expandfilter 4 filterbreakdown*
//*                                     Add more usage for -mvfilter *,?    *
//*                                     Fixed stupid MSFT LDAP URL format   *
//*                           o 05/20   BUGFIX: -e base override            *
//*                                     BUGFIX: jcsv changed to jcsv2       *
//*                                     BUGFIX: otherWellKnownObjects       *
//*                                     BUGFIX: Shortcut doc bug            *
//*                                     BUGFIX: -metamvcsv \0x01\0x01       *
//*                                     BUGFIX: Bug in remove attribs- func *
//*                                     BUGFIX: -sc psomgr sort&displayname *
//*                                     BUGFIX: usage missing -(s)elapsedms *
//*                                     BUGFIX: sddl(not)filter – -> ~      *
//*                                     BUGFIX: Invalid format -tdc(s)fmt   *
//*                           o 05/21   BUGFIX: Fixed usage for tdctzstr    *
//*                                     BUGFIX: -alldc binary attrib decode *
//*                           o 05/23   BUGFIX: LDS appnc user error fix    *
//*                           o 05/26   BUGFIX: crash bug LDS tokengroups   *
//*                                     Added Special base MSA              *
//*                                     BUGFIX: MSDS-Cached-Membership resol*
//*                                     BUGFIX: currenttime preload gtime   *
//*                                     BUGFIX: -fgpp missing usage info    *
//*                           o 05/27   BUGFIX: Fix multiple special bases  *
//*                                     Added -jsd(e)nlb switches           *
//*                                     BUGFIX: SC sitelinkdmp no site speci*
//*                                     BUGFIX: Removed "non-specific" for  *
//*                                             for domain admins, et ali   *
//*                           o 05/29   BUGFIX: added options to sitelinkdmp*
//*                                     BUGFIX: Removed forced base on      *
//*                                             following shortcuts:        *
//*                                               sddldump,getacl           *
//*                                               caclnoinherit,aclnoinherit*
//*                                               cexplaces,explaces        *
//*                           o 05/30   BUGFIX: Bug in jsd(e)nlb with filter*
//*                                     BUGFIX: Add O=* to structure filter *
//*                           o 05/31   BUGFIX: Allow specify position for  *
//*                                               _OBJECT_OWNER "attrib" CSV*
//*                                     BUGFIX: -owneronly not in CSV output*
//*                                     BUGFIX: Added sddl_explicit to allow*
//*                                             for use of -jsde* w/ notfilt*
//*                                     BUGFIX: Fixed nasty silent crash bug*
//*                                             in -decsddlacl, what a PITA *
//*                                     NOTE: All of the SDDL/SD/ACL/SACL/  *
//*                                          SID resolve code ispissingmeoff*
//*                           o 06/01   BUGFIX: Password prompt going into  *
//*                                          CSV output when prompted -up * *
//*                                     BUGFIX: Added -hh / -url to adcsv   *
//*                           o 06/02   FEATUREFIX: Changed mv(not)filter to*
//*                                         to allow multiple values for    *
//*                                         one attr to be specified like   *
//*                                         attr1=val1;val2;val3 instead of *
//*                                         attr1=val1;attr1=val2;attr1=val3*
//*                                     BUGFIX: Fixed non-rfc -url default  *
//*                                     =======LET THE DCRS BEGIN=======    *
//*                                     Added -x (HINT MODE) switch         *
//*                           o 06/03   Added AJ FIX                        *
//*                           o 06/16   Allowed filterbreakdown to use -f   *
//*                                     Alert on -f with no =               *
//*                                     Added -pause                        *
//*                                     Added -norrerr (range retr no err)  *
//*                           o 06/18   ldap SID resolve was broken, fixed  *
//*                           o 06/24   Added msDS-TrustForestTrustInfo to  *
//*                                                -sc trustdmp             *
//*                                     Added addtl trustAttribute decodes  *
//*                                     BUGFIX: Fixed trustType decode MIT  *
//*                                     Changed -ownercsv to not be special *
//*                                     Added -recmutedsq                   *
//*                                     Added -incllike,-excllike           *
//*                                     Added -bb xx  (scope base -b xx)    *
//*                                     Added Replica Set/GUID to -extsrvinf*
//*                           o 06/26   Added -sddlpsflag                   *
//*                                     BUGFIX: non-specific SID resolve for*
//*                                              defaultsecuritydescriptors *
//*                           o 06/28   Added additional OID decodes        *
//*                                     Identify more non-MSFT directories  *
//*                           o 07/01   BUGFIX: Bug in new filter explicits *
//*                           o 07/07   Added -rawsddlexpl                  *
//*                                     Added -rawsddlnl                    *
//*                           o 07/08   Updated how -sddl_epxlicit works,   *
//*                                       uses the -rawsddlnl functiounality*
//*                                     BUGFIX: -nopagingcheck              *
//*                                     Added -alldcd, -alldc + tdcda       *
//*                           o 07/09   BUGFIX: Fixed -bit DNWDATA          *
//*                           o 07/18   BUGFIX: Fixed bug in exterr info for*
//*                                              initial bind functions as  *    
//*                                              well as switching to stdout*
//*                           o 07/20   Added -noerr, when stdout redirect  *
//*                                       will prevent errors going to file *
//*                           o 07/21   Added staticly defined GUIDs that   *
//*                                       MSFT screwed up in schema.        *
//*                                     Started work on MSA password decode *
//*                           o 07/29   BUGFIX: Fixed bug in SID preload w/ *
//*                                       built in mnemonic SIDs            *
//*                           o 08/12   msDS-ManagedPassword decode, not    *
//*                                        sure if it works right lol       *
//*                                     BUGFIX: -ic with -excldn/-incldn    *
//*                           o 8/13    Added -encguidtohex,-dechextoguid   *
//*                                     Added -encsidtohex, -dechextosid    *
//*                           o 08/21   Added noroot param on -sc domainlist*
//*                                     Added -metas, metasl, metasnl       *
//*                           o 09/20   BUGFIX: Decode of oMObjectClass     *
//*                                     INFO: Don’t forget -x with -dsq     *
//*                                     Added -dsnq (-dsq with no quotes)   *
//*                           o 09/21   Updated dsheuristics to show char#s *   
//*                           o 09/22   Decoding of netlogon -ldapping debug*
//*                           o 09/28   Decoding of netlogon completed uses *
//*                                       either -samdc or -rootdsedc       *
//*                                     Switches -ldapping / -ldappingex    *
//*                                         -netlogonexdc (special output)  *
//*                           o 09/29  Bug fix in explicit ACE stripping   *
//*                           o 09/30  BUGFIX: No port listed when -udp     *
//*                                    Added more usage info around -url    *
//*                           o 10/01  Added -acecount                      *
//*                                    Added -fl – formatted list jtsv2 nodn*
//*                                    BUGFIX: Fixed -ef parsing of quotes  *
//*                                    Added :report for -sc fgpps/psos     *
//*                           o 10/04  Added -attrvaldelim, -attrprefix     *
//*                           o 10/06  Updated stdin pipein functionality   *
//*                                    to handle quoted CSV/TSV and filter  *
//*                                    out more garbage fed through the pipe*
//*                                    Add -recmutedsq to usage!!!          *
//*                                    BIN: for password                    *
//*                           o 10/07  Added -dnbreakout <dn>:<tag>         *
//*                           o 10/10  Added -decdelta                      *
//*                           o 10/11  Added currenttime to -extsrvinfo     *
//*                                    Fixed -nirs and nirsx                *
//*                           o 10/12  Added -dpcanonical, -cva             *
//*                           o 10/13  Added !closest to -ldapping/ex       *
//*                                    Added findpropsetrg alias of permguid*
//*                                    Removed -sc domainlist:canonicalname *
//*                                      as it makes no sense at all        *
//*                                    Added -sc domainlist:short option    *
//*                           o 10/14  Added displayname to findpropsetrg   *
//*                           o 10/17  Fixed -nirs/nirsx for real this time *
//*                                    Fixed Garbage DN parsing to handle   *
//*                                      single label domains / ADLDS       *
//*                                    Renamed -x to -hint                  *
//*                           o 10/19  Decode attributesecurityguid with    *
//*                                        -schdc decode switch             *
//*                                    Decode appliesto on controlAccessRght*
//*                                       objects with added -configdc      *
//*                           o 10/20  Added do/do+ alias delobjs/delobjs+  *
//*                                    Allow user to specify parentdn or    *
//*                                      parentcanonical to place anywhere  *
//*                                      within CSV, no need for -p switches*
//*                                    BUGFIX: Detection of config/schema   *
//*                                      partition DNs was broken for cross *
//*                                      forest situations.                 *
//*                           o 10/21  Add -samdc if -netlogonexdc          *
//*                                    Added -xmod (manual admod)           *
//*                                    Added -sc userinfo                   *
//*                           o 10/22  Added shortcuts ldsldapurl:xx,       *
//*                                      ldsldapurl:xx, ldsinstances:xx     *
//*                                    Allow specifying * for -mvsort and   *
//*                                      -mvrsort to sort all MV attribs    *
//*                                    Added -ddo                           *
//*                                    Added -rootdseinternals              *
//*                                    Added virtual LDAPURL/LDAPSURL to    *
//*                                      CRootDSE Class                     *
//*                           o 10/23  BUGFIX: Fixed new bug in CRootDSE 😉 *
//*                           o 10/26  Added jwregex_match function, not    *
//*                                       hooked into anything but -joetest *
//*                           o 11/01  Added -CSVFinalCount                 *
//*                                                                         *
//*                           o 11/02  Moved more errors from stderr>stdout *
//*                                    Fixed filter counts for CSVFinalCount*
//*                           o 11/15  Fixed case insensitive for regex     *
//*                                    Adding regex functionality to all    *
//*                                      DisplayXXX functions               *
//*                           o 11/20  Added more regex functionality       *
//*                                    Fixed some output bugs from regexfunc*
//*                           o 12/11  Moved oid gather details to -d2      *
//*                           o 12/16  Implemented SD regex                 *
//*                                    Updated -jsd* shortcuts to accept    *
//*                                      long form regex m// , s///         *
//*                           o 12/20  RegEx for SDs for CSV mode           *
//*                           o 12/22  Added -sdcsvsingle                   *
//*                           o 12/24  Added better regex input parsing     *
//*                                    Fixed -noerr for STDOUT/ERR          *
//*                                    Added new usage for switches and scs *
//*                                    BUGFIX: empty regex SD showed {SD}   *
//*                           o 12/27  Added -regex?                        *

Rating 4.50 out of 5

8/15/2019

Complexity

by @ 7:27 am. Filed under general, quotes, tech

After, more than <cough>two decades<cough> in a professional role of some sort of ops, engineer, architect, dev ops person in IT or Information Security in very large multinational Fortune 1-50 sized companies I have grown to dislike complexity in a way that some people without my experience may think is unnatural if not completely unhealthy. I have two complexity quotes that I came up with that I like to use and I use them often or very often when I am talking to third party outside consultants or vendors…

1. Complexity kills and scale is a complexity multiplier.

2. Complexity breeds insecurity.

And a third that I didn’t come up with but love and have as one of my primary email signatures at work…

3. A complex system that works is invariably found to have evolved from a simple system that worked. The inverse proposition also appears to be true: A complex system designed from scratch never works and cannot be made to work. You have to start over, beginning with a working simple system.

The last is known as John Gall’s Law or more simply as Gall’s Law[1].

These all feed the corollary which is often stated as K.I.S.S.. Keep It Simple Stupid.

When I am called in to look at problems, the more complexity that is there, generally the worse the problem is. The more unstable it is. The more likely it is to break. The less likely the people supporting it understand it well enough to properly support or in fact, support at all – mostly they just let it run and do a lot of burning of incense around server racks to appease the IT gods. But seriously, the more complex the system, the less likely ANYONE ANYWHERE understands it. 

So when I am called in to sort something out or come up with some sort of initial design, usually my solutions are based on the simple concept, “How do I make this simpler?” or “How do I do this in the most simple way possible?” I visualize supporting it for 5 or 10 or 15 years and what will make this painful if not done properly? When I am called at 2AM to work on it after 2 days of no sleep and I finally got to sleep at 1AM, can I quickly and easily fix it and go back to sleep? And while the generic concept is simple to say (or write), it isn’t always simple to make things simpler, it can, in fact, be very very VERY hard. Like they say, if it were simple, everyone would be doing it. But as hard as it may be, the payoff is the investment in an environment or system that is easier to understand, easier to support, and quite frankly, less likely to break in the first place. The goal of all designers and architects and operational staff and really anyone building any kind of system should be to keep it simple…

Again, repeat it with me, Keep It Simple Stupid.

   joe

[1] https://en.wikiquote.org/wiki/John_Gall

Rating 4.83 out of 5

6/4/2019

Immortalizing AJ Plichta :)

by @ 8:41 am. Filed under general

I have a friend at work named AJ, AJ Plichta, if you must know. Yes, THAT AJ.

AJ likes to type AdFind commands without specifying –f before the filter.

Now for most, this isn’t a huge deal, but when you consider our main work forest has around 2.5 million users this can be a rather cumbersome query to run and usually doesn’t result in the output that he wants and he pings me in Zoom or Jabber and says hey what is wrong with my command?

I then look at the command and smile and laugh out loud and then I type LOL.

For AJ, I agreed to looking into adding something to AdFind to help with this. He asked to please not use his name for the switch… I have acquiesced to his desire, there is not a switch with his name in it…

This fix in the upcoming release of AdFind is for AJ. Open-mouthed smile 

    joe

Comment

//*                           o 06/03   Added AJ FIX                        *

Output…

[Tue 06/04/2019  8:33:43.36]
E:\DEV\cpp\vs\AdFind\Debug>adfind -default "objectclass=user" -dsq

ERROR:
ERROR: Specified attribute contains ‘=’, did you perhaps mean this as an LDAP filter and forgot -f?
ERROR: Argument in question [objectclass=user]
ERROR:

Type AdFind /help or AdFind /? for usage assistance.

Rating 4.50 out of 5

5/16/2019

Working on AdFind V01.52.00 BETA and…

by @ 12:02 am. Filed under tech

For Windows Server 2019 and newer OSes I have decided to add in the numeric portion of the DSA Version String to the “Directory” string that is listed at the top of every run in the header…

Any thoughts, comments, and/or feedback before I lock into the decision?

[Wed 05/15/2019 23:59:16.85]
E:\DEV\cpp\vs\AdFind\Debug>adfind -rootdse -hh lo-dc1.lockout.test.loc dsaversionstring

AdFind V01.52.00cppBETA Joe Richards (support@joeware.net) May 2019

Using server: LO-DC1.lockout.test.loc:389
Directory: Windows Server 2008 R2

dn:
> dsaVersionString: 6.1.7601.23840 (win7sp1_ldr.170610-0600)

1 Objects returned

[Wed 05/15/2019 23:59:21.03]
E:\DEV\cpp\vs\AdFind\Debug>adfind -rootdse -hh lo-dc2.lockout.test.loc dsaversionstring

AdFind V01.52.00cppBETA Joe Richards (support@joeware.net) May 2019

Using server: LO-DC2.lockout.test.loc:389
Directory: Windows Server 2012 R2

dn:
> dsaVersionString: 6.3.9600.19130 (winblue_ltsb_escrow.180823-1003)

1 Objects returned

[Wed 05/15/2019 23:59:29.34]
E:\DEV\cpp\vs\AdFind\Debug>adfind -rootdse -hh lo-dc3.lockout.test.loc dsaversionstring

AdFind V01.52.00cppBETA Joe Richards (support@joeware.net) May 2019

Using server: LO-DC3.lockout.test.loc:389
Directory: Windows Server 2016

dn:
> dsaVersionString: 10.0.14393.2828 (rs1_release_inmarket.190216-1457)

1 Objects returned

[Wed 05/15/2019 23:59:40.54]
E:\DEV\cpp\vs\AdFind\Debug>adfind -rootdse -hh lo-dc4.lockout.test.loc dsaversionstring

AdFind V01.52.00cppBETA Joe Richards (support@joeware.net) May 2019

Using server: LO-DC4.lockout.test.loc:389
Directory: Windows Server 2019 (10.0.17134.1)

dn:
> dsaversionstring: 10.0.17134.1 (WinBuild.160101.0800)

1 Objects returned

[Wed 05/15/2019 23:59:50.50]
E:\DEV\cpp\vs\AdFind\Debug>adfind -rootdse -hh lo-mk19.lockout.test.loc dsaversionstring

AdFind V01.52.00cppBETA Joe Richards (support@joeware.net) May 2019

Using server: LO-MK19.lockout.test.loc:389
Directory: Windows Server 2019 (10.0.17763.1) ADLDS

dn:
> dsaversionstring: 10.0.17763.1 (WinBuild.160101.0800)

1 Objects returned

[Thu 05/16/2019  0:00:02.93]
E:\DEV\cpp\vs\AdFind\Debug>adfind -rootdse -hh lo-ms1903.lockout.test.loc dsaversionstring

AdFind V01.52.00cppBETA Joe Richards (support@joeware.net) May 2019

Using server: LO-MS1903.lockout.test.loc:389
Directory: Windows Server 2019 (10.0.18362.1) ADLDS

dn:
> dsaversionstring: 10.0.18362.1 (WinBuild.160101.0800)

1 Objects returned

[Thu 05/16/2019  0:00:11.75]
E:\DEV\cpp\vs\AdFind\Debug>

Rating 4.00 out of 5

4/2/2019

jwDCLocator.pl *nix/Windows Sample DC Locator Sample Perl Script

by @ 5:03 am. Filed under perl, tech

I have had quite a few people ask me to get to the getting and get the jwDCLocator.pl script made available for them to start looking at it.

So to help those folks out, I am going to do a “quick release” from the Blog and follow up with a release more similar to how I usually release tools on the main website.

You can now find the perl script in a 7zip archive at

https://www.joeware.net/downloads/sharedsource

Note: I have provided a link to the folder itself and enabled indexing so that people can see the whole folder and not think there is something else hidden in there where they can get source code to the other tools, which with the exception of rdp-sec-check (another perl script), is 100% absolutely positively NOT available[1].  I don’t provide source code for the stuff writtin in c/c++, don’t bother asking. I might change my mind in the future but it will be me changing my mind, not someone coercing or convincing me to change my mind.

As of right now, take a look at the usage in the script

jwDCLocator.pl /?

Or look at the code itself. You can run with an INI config file or with command line options. The simplest examples of running the script are

perl jwdclocator.pl /domain:k16tst.test.loc

and

perl jwdclocator.pl /domain:k16tst.test.loc /gclist

I have tested on CentOS7 and FreeBSD12 as well as Windows Server 2012 R2, Windows 10 1809, Windows Server 2016, and Windows Server 2019. For Windows Server both full and core.

For CentOS7 and FreeBSD12 I had to upgrade from perl V5.14 to perl 5.26 (or newer). There is some hashing functionality in the initial script that needs the alias/reference stuff in 5.26. Stuff that was apparently there before in older versions of perl that I swear I had used back in the 90’s for some monitoring scripts (I need to go look closer at those old scripts) but it seemed to have been lost along the way. I also needed to install Net::DNS and Net::LDAP.

For Windows I had to install perl 5.26 (or newer – usually Strawberry 5.28). Same reason for versioning as mentioned above. I also had to install Net::LDAP, Net::DNS was already there.

Mini-FAQ:

Q: Hey dude, I am getting weird results…

A: Feel free to run with the /verbose and /debug switches and then send me a text capture (not image) of the run screen including the command and all files created if you want me to look at it. If you have modified the script, share with me exactly what you did. As per my normal joeware warranty, I will try to look at it when I can, I may or may not fix it. 

Q: Hey joe, where you going with that gun in your hand?

A: Haha. Excellent, never heard that one before…

Q: When will you release this in other script languages?

A: Maybe never. If you want it in another language, feel free to do it and then you can send it to me and I may (or may not) put it in the 7zip file with the perl script. I have to look at the code and feel comfortable with it if I am going to share it on my site. You understand of course.

Q: Can I incorporate this intellectual property in my program?

A: ABSOLUTELY YES. You have unrestricted rights to use anything in this script in any code you write nor and forever.

That is the whole point behind WHY I spent nights working on this so that I could make it hopefully simple to read and understand so that people would use this knowledge and understanding and actually implement this functionality in their code. Please acknowledge me somewhere saying hey, this dude really helped us out to make our product better but even that isn’t a requirement. I JUST WANT THE CODE OUT THERE IN THE WILD RELATED TO ACTIVE DIRECTORY TO GET BETTER. I truly love this technology and think MSFT changed the world with it and I have had 20 years of salary directly related to it. I expect to have many more. And if people start writing code to properly use it, well my life and the lives of many friends and many tens of thousands of people I have never met get better. This will help, hopefully, to remove some stupid from the world.

Too many companies out there pretend to be AD integrated or AD compatible when what they really mean is that they simply have an LDAP interface. I’m sorry to burst your bubble, that doesn’t make you AD integrated or AD compatible. You have multiple bars there, you can do LDAP? Great, that means you can see AD, that doesn’t mean you are integrated or compatible. You need to be able to find domain controllers properly with actual redundancy/high availability, you need to understand multiple domains in a single forest, you need to understand Global Catalog versus Domain. If I ask you about redundancy and availability and your response is something like give me a VIP/Load Balancer to point at I will look at you in disdain. If you want to use AD and you want to use LDAP, in particular, to hit AD. Do it right because you aren’t doing anyone any favors otherwise. I am looking at you IBM and your WebSphere product line in particular (which I pointed out to your ridiculously priced internal consultants all the way back in 2001 sucked and how you could fix it when I was at Ford Motor and your consultants were trying to say AD was failing), I am looking at you VMware, I am looking at you Splunk, so many companies, so little time. 

If you think wow, this was really helpful and will make our product or my code or my scripts or whatever better, please consider the donate button up in the corner. Or not. That is entirely up to you. It is just a form of recognition and a statement to the value you think this stuff brings you. I am not starving but I won’t snub my nose at financial forms of appreciation either. Open-mouthed smile 

That’s it for now. More later. I have a new script I am working on specifically for *nix machines now to help further the admins/support teams in that space.

   joe

[1] Well I did share the source code to one small tool to Kevin Mitnick (yes that Kevin Mitnick – and you all thought I was boring…) a few years back. Hackers seem to love me. Sometimes I wonder if I wasted my life being on the good side of IT and Security instead of being on the shadier side. Winking smile

Rating 4.75 out of 5

3/31/2019

LDAP Ping and Determining Your Machine’s Site

by @ 8:09 pm. Filed under tech

Microsoft has a specific method for returning basic information that can be used for finding what site (and what is the next closest site) for any given machine that reaches out to a domain controller with a LDAP query. Originally the query had to be performed over CLDAP (connectionless LDAP aka UDP LDAP) but sometime in the Windows Server 2003 timeframe it became available via both UDP and TCP. Personally I like the TCP ping over the UDP ping because no applications are actually using UDP to use AD and this functionality.

The "ping" is a specially crafted anonymous LDAP query that retrieves the NetLogon attribute from the RootDSE of a Domain Controller which then returns the attribute in one of several available BLOB formats. The information returned useful for bootstrapping and validation and in particular for this specific topic, finding out which AD site the client is in. The "LDAP Ping" is documented fully in section 6.3 “Publishing and Locating a Domain Controller” of the Microsoft MS-ADTS Protocol Documentation including the various BLOB structures. Note that when it says something is Big-Endian, pay attention, it is critical to getting a response back.

The key pages are:

6.3 Publishing and Locating a Domain Controller   — Base of all of the documentation

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/8ebcf782-87fd-4dc3-8585-1301569dfe4f

6.3.1 Structures and Constants

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/b3006506-4338-45ef-ac52-1e7d5c9c46e9

6.3.3. LDAP Ping

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/895a7744-aff3-4f64-bcfa-f8c05915d2e9

6.3.7 Name Compression and Decompression

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/b0ef9479-78d8-40c1-b6d2-0baad834ed39

I will be releasing a full platform agnostic anonymous DC Locator perl script in the relatively near term that has this implemented as part of the code along with the DNS lookups and some validation tests. I also have generated some notes and a DCR to implement the decoding of this data in AdFind as well. As it is, this is what AdFind will show you right now if you attempt to query for this information:

[Fri 03/29/2019 23:07:04.51]
E:\DEV\Schema>adfind -rootdseanon -f "&(host=k16tst-dc1)(ntver=\04\00\00\00)" -s one netlogon

AdFind V01.51.00cpp Joe Richards (support@joeware.net) October 2017

Using server: K16TST-DC1.k16tst.test.loc:389
Directory: Windows Server 2016

dn:
> netlogon: 1700 0000 FDF1 0100 9011 FD98 67E1 3447 A585 7981 238A 135E 066B 3136 7473 7404 7465 7374 036C 6F63 00C0 180A 4B31 3654 5354 2D44 4331 C018 064B 3136 5453 5400 0A4B 3136 5453 542D 4443 3100 0017 4465 6661 756C 742D 4669 7273 742D 5369 7465 2D4E 616D 6500 136A 6F65 6E65 746C 6F67 6F6E 7465 7374 7369 7465 0005 0000 00FF FFFF FF

1 Objects returned

This is what WireShark will show you:

SNAGHTML4475a203

Now you can also implement the “next closest site” functionality as well with the following query (and this is what jwDCLocator.pl uses)… With this one I needed to specify a specific DC in another site as well as change the ntver attribute value to include NETLOGON_NT_VERSION_WITH_CLOSEST_SITE so that the proper extra info would be sent along…

[Fri 03/29/2019 23:08:14.64]
E:\DEV\Schema>adfind -hh k16tst-scdc1.k16tst.test.loc -rootdseanon -f "&(host=k16tst-scdc1)(ntver=\14\00\00\00)" -s one netlogon

AdFind V01.51.00cpp Joe Richards (support@joeware.net) October 2017

Using server: K16TST-SCDC1.k16tst.test.loc:389
Directory: Windows Server 2016

dn:
> netlogon: 1800 0000 7CF1 0100 9011 FD98 67E1 3447 A585 7981 238A 135E 066B 3136 7473 7404 7465 7374 036C 6F63 00C0 180C 4B31 3654 5354 2D53 4344 4331 C018 064B 3136 5453 5400 0C4B 3136 5453 542D 5343 4443 3100 0005 5369 7465 3200 136A 6F65 6E65 746C 6F67 6F6E 7465 7374 7369 7465 0017 4465 6661 756C 742D 4669 7273 742D 5369 7465 2D4E 616D 6500 1500 0000 FFFF FFFF

1 Objects returned

Unfortunately WireShark gets lost for this extra data and so it doesn’t display really anything…

SNAGHTML4478f6bb

But if you look down in the packet bytes data you will see it…

SNAGHTML4479c064

which you can see three site names in it…

And of course jwDCLocator.pl knows how to decode it properly…

Dynamically determining site…
  Sending LDAP Ping to LDAP://k16tst-scdc1.k16tst.test.loc:389…
  AutoDetected Server Site             : Site2
  AutoDetected Client Site             : joenetlogontestsite
  AutoDetected Client Next Closest Site: Default-First-Site-Name
Determining site specific DNS records…

The binary (with and without the closest site flag in the query) is described by the structure that can be found at

6.3.1.9 NETLOGON_SAM_LOGON_RESPONSE_EX

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/8401a33f-34a8-40ca-bf03-c3484b66265f

Extracting the information from this structure is not quite as straightforward as what you normally get in that they are compressing the names as described in RFC 1035 – “Domain Names – Implementation and Specification” which is further described in the page mentioned above, 6.3.7 Name Compression and Decompression. Note that when I was writing my perl script I hadn’t seen this page yet so I just looked at the binary and shook my head a few times to clear cobwebs and reversed it out. That means that my original perl script may be implemented slightly differently than what is described and it also means I cannot actually vouchsafe for the pseudocode given on the page so if you use it directly, validate it versus just assume it is 100%. But that goes for all documentation from all vendors at all times. Smile 

Note that Perl has some functionality in the Net::DNS module that will decode these for you but I wanted to be as raw as possible in the code to allow people to be able to take the code and change to any language, framework, platform they wanted and be able to do something. Hiding some of the details like this by using other modules defeats that mindset a little.

Now for some samples from jwDCLocator.pl decoding some of compressed string in the structure. As the structure is decoded, a table will be created with strings that are referred to, this is used for the “compression” functionality. If the string isn’t in the table already you will get a length value and the string. If part of the string is in the table (as part of another string response) then you will get whatever part is unique as the length and string and then a pointer to the rest of the string. For clarity of the following examples, this is the table that gets built in memory as the structure is unpacked:

’24’ => ‘k16tst.test.loc’,
’41’ => ‘k16tst.test.loc’,
’43’ => ‘K16TST-SCDC1.k16tst.test.loc’,
’58’ => ‘K16TST’,
’66’ => ‘K16TST-SCDC1’
’80’ => ”,
’81’ => ‘Site2’,
’88’ => ‘joenetlogontestsite’,
‘109’ => ‘Default-First-Site-Name’,

First, the DNS Forest Name.

SNAGHTML4cf5c580

20190331-144158.89286: DEBUG: NETLOGON REMAINING=066b31367473740474657374036c6f6300c0180a4b313654535
                                                  42d444332c018064b3136545354000a4b31365453542d444332
                                                 000005536974653200136a6f656e65746c6f676f6e746573747
                                                  3697465001744656661756c742d46697273742d536974652d4e
                                                  616d650015000000ffffffff
  20190331-144158.89290: DEBUG: Enter GetCompressedName…
  20190331-144158.89293: DEBUG: +++++++++++++++++++++
  20190331-144158.89296: DEBUG: Start Data     : 066b31367473740474657374036c6f6300c0180a4b3136545354
                                                 2d444332c018064b3136545354000a4b31365453542d44433200
                                                 0005536974653200136a6f656e65746c6f676f6e746573747369
                                                 7465001744656661756c742d46697273742d536974652d4e616d
                                                 650015000000ffffffff
  20190331-144158.89299: DEBUG: Enter GetXChars…
  20190331-144158.89303: DEBUG: Short Hint     : 0
  20190331-144158.89306: DEBUG: Enter GetXChars…
  20190331-144158.89309: DEBUG: Full Hint      : 06
  20190331-144158.89313: DEBUG: Enter GetXChars…
  20190331-144158.89317: DEBUG: Enter HexToASCII…
  20190331-144158.89322: DEBUG: String         : k16tst
  20190331-144158.89330: DEBUG: Full String    : k16tst.
  20190331-144158.89338: DEBUG: ———————
  20190331-144158.89346: DEBUG: +++++++++++++++++++++
  20190331-144158.89352: DEBUG: Start Data     : 0474657374036c6f6300c0180a4b31365453542d444332c018064
                                                 b3136545354000a4b31365453542d444332000005536974653200
                                                 136a6f656e65746c6f676f6e74657374736974650017446566617
                                                 56c742d46697273742d536974652d4e616d650015000000ffffff
                                                ff
  20190331-144158.89357: DEBUG: Enter GetXChars…
  20190331-144158.89364: DEBUG: Short Hint     : 0
  20190331-144158.89370: DEBUG: Enter GetXChars…
  20190331-144158.89376: DEBUG: Full Hint      : 04
  20190331-144158.89382: DEBUG: Enter GetXChars…
  20190331-144158.89388: DEBUG: Enter HexToASCII…
  20190331-144158.89395: DEBUG: String         : test
  20190331-144158.89401: DEBUG: Full String    : k16tst.test.
  20190331-144158.89407: DEBUG: ———————
  20190331-144158.89413: DEBUG: +++++++++++++++++++++
  20190331-144158.89418: DEBUG: Start Data     : 036c6f6300c0180a4b31365453542d444332c018064b313654535
                                                 4000a4b31365453542d444332000005536974653200136a6f656e
                                                65746c6f676f6e7465737473697465001744656661756c742d466
                                                 97273742d536974652d4e616d650015000000ffffffff
  20190331-144158.89424: DEBUG: Enter GetXChars…
  20190331-144158.89431: DEBUG: Short Hint     : 0
  20190331-144158.89437: DEBUG: Enter GetXChars…
  20190331-144158.89451: DEBUG: Full Hint      : 03
  20190331-144158.89456: DEBUG: Enter GetXChars…
  20190331-144158.89459: DEBUG: Enter HexToASCII…
  20190331-144158.89463: DEBUG: String         : loc
  20190331-144158.89466: DEBUG: Full String    : k16tst.test.loc.
  20190331-144158.89468: DEBUG: ———————
  20190331-144158.89471: DEBUG: +++++++++++++++++++++
  20190331-144158.89474: DEBUG: Start Data     : 00c0180a4b31365453542d444332c018064b3136545354000a4b3
                                                1365453542d444332000005536974653200136a6f656e65746c6f
                                                 676f6e7465737473697465001744656661756c742d46697273742
                                                 d536974652d4e616d650015000000ffffffff
  20190331-144158.89478: DEBUG: Enter GetXChars…
  20190331-144158.89481: DEBUG: Short Hint     : 0
  20190331-144158.89484: DEBUG: Enter GetXChars…
  20190331-144158.89486: DEBUG: Full Hint      : 00
  20190331-144158.89490: DEBUG: FINAL Full String: k16tst.test.loc

And here is the cool part… On the next bit, getting the DNS Domain Name

SNAGHTML4d0097b4

20190328-220801.19632: DEBUG: Enter GetCompressedName…
20190328-220801.19635: DEBUG: +++++++++++++++++++++
20190328-220801.19638: DEBUG: Start Data     : c0180a4b31365453542d444331c018064b3136545354000a4b3136
                                               5453542d44433100001744656661756c742d46697273742d536974
                                                652d4e616d6500136a6f656e65746c6f676f6e7465737473697465
                                                00c04d15000000ffffffff
20190328-220801.19641: DEBUG: Enter GetXChars…
20190328-220801.19644: DEBUG: Short Hint     : c
20190328-220801.19646: DEBUG: Enter GetXChars…
20190328-220801.19649: DEBUG: Compression Offset — 0x0018 — 24
20190328-220801.19652: DEBUG: FINAL Full String: k16tst.test.loc

And then the Host’s FQDN…

SNAGHTML4d029b74

20190328-220801.19666: DEBUG: Enter GetCompressedName…
20190328-220801.19667: DEBUG: +++++++++++++++++++++
20190328-220801.19668: DEBUG: Start Data     : 0a4b31365453542d444331c018064b3136545354000a4b31365453
                                                542d44433100001744656661756c742d46697273742d536974652d
                                                4e616d6500136a6f656e65746c6f676f6e746573747369746500c0
                                                4d15000000ffffffff
20190328-220801.19669: DEBUG: Enter GetXChars…
20190328-220801.19670: DEBUG: Short Hint     : 0
20190328-220801.19671: DEBUG: Enter GetXChars…
20190328-220801.19672: DEBUG: Full Hint      : 0a
20190328-220801.19673: DEBUG: Enter GetXChars…
20190328-220801.19674: DEBUG: Enter HexToASCII…
20190328-220801.19676: DEBUG: String         : K16TST-DC1
20190328-220801.19677: DEBUG: Full String    : K16TST-DC1.
20190328-220801.19678: DEBUG: ———————
20190328-220801.19679: DEBUG: +++++++++++++++++++++
20190328-220801.19680: DEBUG: Start Data     : c018064b3136545354000a4b31365453542d444331000017446566
                                                61756c742d46697273742d536974652d4e616d6500136a6f656e65
                                                746c6f676f6e746573747369746500c04d15000000ffffffff
20190328-220801.19681: DEBUG: Enter GetXChars…
20190328-220801.19682: DEBUG: Short Hint     : c
20190328-220801.19683: DEBUG: Enter GetXChars…
20190328-220801.19684: DEBUG: Compression Offset — 0x0018 — 24
20190328-220801.19685: DEBUG: FINAL Full String: K16TST-DC1.k16tst.test.loc

Rating 4.60 out of 5

3/26/2019

And FreeBSD12 has been tested…

by @ 10:34 pm. Filed under perl, tech

No changes to the script…

$ uname -mrs
FreeBSD 12.0-RELEASE amd64
$ perl jwDCLocator_linux.pl /domain:k16tst.test.loc

jwDCLocator V01.02.00pl  Joe Richards (support@joeware.net)  March 2019

Initializing Logging to logfile 20190326-2229-jwDCLocator.log…
Reading configuration file jwDCLocator.config…
Configuration file does not exist, skipping…
Determining bootstrap domain controllers via DNS for k16tst.test.loc…
  BootStrap Hosts: k16tst-dc1.k16tst.test.loc k16tst-scdc1.k16tst.test.loc k16tst-dc2.k16tst.test.loc
Dynamically determining site…
  Sending LDAP Ping to LDAP://k16tst-dc1.k16tst.test.loc:389…
  AutoDetected Server Site             : Default-First-Site-Name
  AutoDetected Client Site             : Site2
  AutoDetected Client Next Closest Site: Default-First-Site-Name
Determining site specific DNS records…
Dynamically determining domain k16tst.test.loc site specific domain controllers for site Site2…
Dynamically determining domain k16tst.test.loc site specific domain controllers for site Default-First-Site-Name…
Validating DCs for Site2…(Order=0)
      k16tst-dc2.k16tst.test.loc…
        TCP LDAP PING…
          Sending LDAP Ping to LDAP://k16tst-dc2.k16tst.test.loc:389…
          DC Site     = Site2
          ElapsedTime = 0.006692
     Retrieving RootDSE…
          Synchronized = TRUE
          ElapsedTime  = 0.021649
      k16tst-scdc1.k16tst.test.loc…
        TCP LDAP PING…
          Sending LDAP Ping to LDAP://k16tst-scdc1.k16tst.test.loc:389…
          DC Site     = Site2
          ElapsedTime = 0.006101
     Retrieving RootDSE…
          Synchronized = TRUE
          ElapsedTime  = 0.017424
Validating DCs for Default-First-Site-Name…(Order=1)
       k16tst-dc1.k16tst.test.loc…
        TCP LDAP PING…
           Sending LDAP Ping to LDAP://k16tst-dc1.k16tst.test.loc:389…
          DC Site     = Default-First-Site-Name
          ElapsedTime = 0.013375
     Retrieving RootDSE…
          Synchronized = TRUE
          ElapsedTime  = 0.037377
Checking Validation List for PDC domain controllers
Ordering DCs by Site | Priority | Avg Elapsed Response Time…
Sorted Validated Domain Controller List
k16tst-dc2.k16tst.test.loc
k16tst-scdc1.k16tst.test.loc
k16tst-dc1.k16tst.test.loc

The command completed.
$

Rating 3.00 out of 5

3/22/2019

So very close… Reasonable Effort Platform Agnostic Perl Script That Implements the Active Directory DC Locator Process…

by @ 12:09 am. Filed under perl, tech

Getting very close to being ready to release the reasonable effort platform agnostic version perl script that will run through the DC Locator process.

Note that I intend for this to be a fairly robust script. It finds server (domain controller) site, client site, and next closest site. It polls the DCs validating them to make sure they are responding (so not behind a firewall or otherwise not responding) and have other specific items right (obviously you could tweak the validation rules as you need[1]). Once it has a list and validates the DCs on the list it then rates them based on response time performance and DNS Priority. If using multiple DCs to load balance multiple requests to multiple domain controllers (highly recommended for performance and stability for reads) you can easily see how to add in weighting logic.

The code is extremely long winded (nearly 2000 lines) with lots of comments and whitespace to make it mostly readable so people can take it and use any parts of it that are desired and convert to whatever languages are needed. The actual hardcore parts of it could be easily reduced down and in fact yanked out and put into other code. In fact that is the whole intent. In part of the code I actually have comments of:

#
# Function AnonLDAPPing
#  Requires the Net::LDAP module
#   This is where the totally cool stuff starts!!!
#   No seriously, I don’t think I have ever seen
#   this in simple basic open code anywhere before. It
#   uses the same dynamic underlying processes to
#   determine the site the client is in that is used
#   by Windows.
#  
#
sub AnonLDAPPing

Oh and that AnonLDAPPing function… It works over TCP, it doesn’t use UDP like everyone else I have seen. That is so if you have a network that likes to chop down UDP packets you don’t have to care about it. Also I think using TCP to perform the ping and get the response timings is more realistic anyway. You can change it to UDP if you like… I don’t care. Depending on the language you use it could be more or less painful.

I spent a little time the last couple of nights building a new CentOS 7 server and spending time trying to get reacquainted with CentOS and upgrading perl to 5.26. I need to do the same with FreeBSD12.0 next. Once I get done with FreeBSD12.0 then I will wrap up the specifics needed for each (use/requires/modules that need to be loaded[2]) so I can put it all in a single script. This has taken longer than expected as my real job has been excessively involved the last few months and even more so the last few weeks. I have to say writing my “for fun” code keeps me sane though. Who knows how long ago my brain would have melted down from nearly 25 years working in the Enterprise Class Fortune X company space. My first Enterprise job was at Ford when it was in the Fortune and Global 5 category, I have been in the Fortune/Global 30 or bigger since. Now I am back up in the Fortune/Global 5 again.  

I will expand more about support of the script when I finally release it but short and simple… this will be unsupported code. If you have questions you will be able to send them, I might respond; if you dump a bunch of money into my tip jar, I might be more likely to respond. The times people have done that I don’t think they have been disappointed, though “a bunch” is my definition. Smile  Anyway, my previous forays into shared source code went horribly with people making changes and compiling and then expecting me to figure out what was wrong while not telling me they changed something. I have learned a lot since then and released the perl script rdp_sec_check which was a modification of another security teams tool that made it more useful for me and I didn’t have any issues with that but just the same I still have a bad taste in my mouth about that initial code sharing… I do have to admit though that sharing this code could be VERY USEFUL for people who still need to find domain controllers since the free stuff out there, and quite frankly a lot of the expensive stuff, either can’t do this work or can’t do it well (or absolutely in a pretty shitty half ass dip the toe in the water to say they did it manner).

Good day and may the good news be yours. Just kidding

    joe

[1] …say you are pretending to be a Windows Hello for Business Client in Hybrid Key Mode and can only use Windows Server 2016 domain controllers because earlier stuff can’t process the WH4B commands properly and the later stuff (Windows Server 2019) has a code regression bug that doesn’t allow it to work either (allegedly)…

[2] There is currently, and literally, one single “use” line commented out of nearly 2000 lines of script in the CentOS7 version compared to the Windows version and I intend to get that handled so there is no difference.

Windows 10 Pro 1809

[Thu 03/21/2019 23:01:19.71]
E:\DEV\perl\jwDCLocator>perl jwDCLocator.pl /domain:k16tst.test.loc

jwDCLocator V01.01.00pl  Joe Richards (support@joeware.net)  March 2018

Initializing Logging to logfile 20190321-2301-jwDCLocator.log…
Reading configuration file jwDCLocator.config…
Processing configuration file…
Configuration file does not exist, skipping…
Determining bootstrap domain controllers via DNS for k16tst.test.loc…
  BootStrap Hosts: k16tst-scdc1.k16tst.test.loc k16tst-dc2.k16tst.test.loc k16tst-dc1.k16tst.test.loc
Dynamically determining site…
  Sending LDAP Ping to LDAP://k16tst-scdc1.k16tst.test.loc:389…
  AutoDetected Server Site             : Site2
  AutoDetected Client Site             : joenetlogontestsite
  AutoDetected Client Next Closest Site: Default-First-Site-Name
Determining site specific DNS records…
Dynamically determining domain k16tst.test.loc site specific domain controllers for site joenetlogontestsite…
Dynamically determining domain k16tst.test.loc site specific domain controllers for site Default-First-Site-Name…
Validating DCs for joenetlogontestsite…(Order=0)
      k16tst-dc1.k16tst.test.loc…
        TCP LDAP PING…
           Sending LDAP Ping to LDAP://k16tst-dc1.k16tst.test.loc:389…
          DC Site     = Default-First-Site-Name
          ElapsedTime = 0.011377
     Retrieving RootDSE…
          Synchronized = TRUE
          ElapsedTime  = 0.010118
Validating DCs for Default-First-Site-Name…(Order=1)
      k16tst-dc1.k16tst.test.loc…
        TCP LDAP PING…
          Sending LDAP Ping to LDAP://k16tst-dc1.k16tst.test.loc:389…
          DC Site     = Default-First-Site-Name
          ElapsedTime = 0.008036
      Retrieving RootDSE…
          Synchronized = TRUE
          ElapsedTime  = 0.008876
Checking Validation List for PDC domain controllers
Ordering DCs by Site | Priority | Avg Elapsed Response Time…
Sorted Validated Domain Controller List
k16tst-dc1.k16tst.test.loc
k16tst-dc1.k16tst.test.loc

The command completed.

CentOS Linux release 7.6.1810 (Core)

[joe@centos7-1 AD]$

[joe@centos7-1 AD]$ perl jwDCLocator_linux.pl /domain:k16tst.test.loc

jwDCLocator V01.02.00pl  Joe Richards (support@joeware.net)  March 2018

Initializing Logging to logfile 20190321-2329-jwDCLocator.log…
Reading configuration file jwDCLocator.config…
Processing configuration file…
Configuration file does not exist, skipping…
Determining bootstrap domain controllers via DNS for k16tst.test.loc…
  BootStrap Hosts: k16tst-dc1.k16tst.test.loc k16tst-scdc1.k16tst.test.loc k16tst-dc2.k16tst.test.loc
Dynamically determining site…
  Sending LDAP Ping to LDAP://k16tst-dc1.k16tst.test.loc:389…
  AutoDetected Server Site             : Default-First-Site-Name
  AutoDetected Client Site             : Site2
  AutoDetected Client Next Closest Site: Default-First-Site-Name
Determining site specific DNS records…
Dynamically determining domain k16tst.test.loc site specific domain controllers for site Site2…
Dynamically determining domain k16tst.test.loc site specific domain controllers for site Default-First-Site-Name…
Validating DCs for Site2…(Order=0)
       k16tst-dc2.k16tst.test.loc…
        TCP LDAP PING…
           Sending LDAP Ping to LDAP://k16tst-dc2.k16tst.test.loc:389…
          DC Site     = Site2
          ElapsedTime = 0.00778
     Retrieving RootDSE…
          Synchronized = TRUE     
          ElapsedTime  = 0.031609
      k16tst-scdc1.k16tst.test.loc…
        TCP LDAP PING…
          Sending LDAP Ping to LDAP://k16tst-scdc1.k16tst.test.loc:389…
          DC Site     = Site2
          ElapsedTime = 0.00709
     Retrieving RootDSE…     
          Synchronized = TRUE
          ElapsedTime  = 0.042098
Validating DCs for Default-First-Site-Name…(Order=1)
      k16tst-dc1.k16tst.test.loc…
        TCP LDAP PING…
          Sending LDAP Ping to LDAP://k16tst-dc1.k16tst.test.loc:389…
          DC Site     = Default-First-Site-Name
          ElapsedTime = 0.008532
     Retrieving RootDSE…
          Synchronized = TRUE
          ElapsedTime  = 0.007037
Checking Validation List for PDC domain controllers
Ordering DCs by Site | Priority | Avg Elapsed Response Time…
Sorted Validated Domain Controller List
k16tst-scdc1.k16tst.test.loc
k16tst-dc2.k16tst.test.loc
k16tst-dc1.k16tst.test.loc

The command completed.
[joe@centos7-1 AD]$

Rating 4.33 out of 5

[joeware – never stop exploring… :) is proudly powered by WordPress.]