peass-ng/PEASS-ng · error · Win32Exception

Win32Exception

Error message

Win32Exception

What it means

CrackNames calls DsCrackNames and throws Win32Exception when the API itself fails (returned error code is not DS_NAME_NO_ERROR), e.g. RPC failures to the DC, invalid handle, or access denied. This is an API-level failure distinct from error 306's per-name status failure: here the whole call failed.

Source

Thrown at winPEAS/winPEASexe/winPEAS/TaskScheduler/TaskEditor/Native/NTDSAPI.cs:89

                if (res == null || res.Length == 0 || res[0].status != DS_NAME_ERROR.DS_NAME_NO_ERROR)
                    throw new SecurityException("Unable to resolve user name.");
                return res[0].pName;
            }

            /// <summary>
            /// Converts an array of directory service object names from one format to another. Name conversion enables client applications to map between the multiple names used to identify various directory service objects. 
            /// </summary>
            /// <param name="names">The names to convert.</param>
            /// <param name="flags">Values used to determine how the name syntax will be cracked.</param>
            /// <param name="formatOffered">Format of the input names.</param>
            /// <param name="formatDesired">Desired format for the output names.</param>
            /// <returns>An array of DS_NAME_RESULT_ITEM structures. Each element of this array represents a single converted name.</returns>
            public DS_NAME_RESULT_ITEM[] CrackNames(string[] names = null, DS_NAME_FLAGS flags = DS_NAME_FLAGS.DS_NAME_NO_FLAGS, DS_NAME_FORMAT formatOffered = DS_NAME_FORMAT.DS_UNKNOWN_NAME, DS_NAME_FORMAT formatDesired = DS_NAME_FORMAT.DS_USER_PRINCIPAL_NAME)
            {
                IntPtr pResult;
                uint err = Ntdsapi.DsCrackNames(handle, flags, formatOffered, formatDesired, (uint)(names?.Length ?? 0), names, out pResult);
                if (err != (uint)DS_NAME_ERROR.DS_NAME_NO_ERROR)
                    throw new System.ComponentModel.Win32Exception((int)err);
                try
                {
                    // Next convert the returned structure to managed environment
                    DS_NAME_RESULT Result = (DS_NAME_RESULT)Marshal.PtrToStructure(pResult, typeof(DS_NAME_RESULT));
                    return Result.Items;
                }
                finally
                {
                    Ntdsapi.DsFreeNameResult(pResult);
                }
            }

            public void Dispose()
            {
                uint ret = Ntdsapi.DsUnBind(ref handle);
                System.Diagnostics.Debug.WriteLineIf(ret != 0, "Error unbinding :\t" + ret.ToString());
            }
        }

View on GitHub (pinned to 53fb989abc)

Solutions

  1. Confirm DsBind succeeded and domain controller connectivity (test RPC/LSA access to the DC)
  2. Check Win32Exception.NativeErrorCode to identify the specific failure (5=access denied, 1722=RPC unavailable) and fix network/permissions accordingly
  3. Retry on transient RPC errors after connectivity is restored
  4. Catch Win32Exception around CrackNames and degrade to unconverted names

Example fix

// before
var items = ntdsApi.CrackNames(new[] { name });
// after
try { items = ntdsApi.CrackNames(new[] { name }); }
catch (Win32Exception ex) { Log($"DsCrackNames failed: {ex.NativeErrorCode}"); items = null; }
Defensive patterns

Strategy: try-catch

Validate before calling

using (var ctx = new System.DirectoryServices.AccountManagement.PrincipalContext(System.DirectoryServices.AccountManagement.ContextType.Domain)) { /* validates domain access */ }

Try / catch

try { items = api.CrackNames(names); } catch (Win32Exception ex) { Log($"DsCrackNames error {ex.NativeErrorCode}"); items = null; }

Prevention

When it happens

Trigger: Calling CrackNames when the DsCrackNames P/Invoke returns a Win32 error — invalid DsBind handle, no DC reachable, RPC unavailable, or access-denied conditions — propagating the raw error code into Win32Exception at NTDSAPI.cs:89.

Common situations: Client machine not domain-joined or DC offline/firewalled (RPC ports blocked); expired machine credentials; calling name translation with a handle bound to an unavailable domain.

Related errors


AI-assisted analysis of peass-ng/PEASS-ng@53fb989abc (2026-09-02). Data as JSON: /api/errors/09fe861ec0d8c6f2. Report an issue: GitHub.