void impersonateToGetData(PCSTR user, PCSTR domain, PCSTR password, PCSTR kdc, PSID *sid, DWORD *rid, PCSTR usingWhat) { NTSTATUS status; DWORD ret, *aRid, *usage; ANSI_STRING aUser, aKdc, aDomain, aPass, aProg; UNICODE_STRING uUser, uKdc, uDomain, uPass, uProg; SAMPR_HANDLE hServerHandle, hDomainHandle; PSID domainSid; HANDLE hToken, hNewToken; PROCESS_INFORMATION processInfos; STARTUPINFOW startupInfo; RtlZeroMemory(&startupInfo, sizeof(STARTUPINFOW)); startupInfo.cb = sizeof(STARTUPINFOW); RtlInitString(&aUser, user); RtlInitString(&aKdc, kdc); RtlInitString(&aDomain, domain); RtlInitString(&aPass, password); RtlInitString(&aProg, usingWhat ? usingWhat : "winver.exe"); if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uUser, &aUser, TRUE))) { if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uKdc, &aKdc, TRUE))) { if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uDomain, &aDomain, TRUE))) { if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uPass, &aPass, TRUE))) { if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uProg, &aProg, TRUE))) { if(CreateProcessWithLogonW(uUser.Buffer, uDomain.Buffer, uPass.Buffer, LOGON_NETCREDENTIALS_ONLY, uProg.Buffer, NULL, CREATE_SUSPENDED, NULL, NULL, &startupInfo, &processInfos)) { if(OpenProcessToken(processInfos.hProcess, TOKEN_DUPLICATE, &hToken)) { if(DuplicateTokenEx(hToken, TOKEN_QUERY | TOKEN_IMPERSONATE, NULL, SecurityDelegation, TokenImpersonation, &hNewToken)) { if(SetThreadToken(NULL, hNewToken)) { kprintf("[AUTH] Impersonation\n"); if(!(*sid && *rid)) { kprintf("[SID/RID] \'%s @ %s\' must be translated to SID/RID\n", user, domain); status = SamConnect(&uKdc, &hServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, FALSE); if(NT_SUCCESS(status)) { status = SamLookupDomainInSamServer(hServerHandle, &uDomain, &domainSid); if(NT_SUCCESS(status)) { status = SamOpenDomain(hServerHandle, DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP, domainSid, &hDomainHandle); if(NT_SUCCESS(status)) { status = SamLookupNamesInDomain(hDomainHandle, 1, &uUser, &aRid, &usage); if(NT_SUCCESS(status)) *rid = *aRid; else PRINT_ERROR("SamLookupNamesInDomain %08x\n", status); } else PRINT_ERROR("SamOpenDomain %08x\n", status); ret = GetLengthSid(domainSid); if(*sid = (PSID) LocalAlloc(LPTR, ret)) { if(!CopySid(ret, *sid, domainSid)) { *sid = (PSID) LocalFree(*sid); PRINT_ERROR_AUTO("CopySid"); } } SamFreeMemory(domainSid); } else PRINT_ERROR("SamLookupDomainInSamServer %08x\n", status); SamCloseHandle(hServerHandle); } else PRINT_ERROR("SamConnect %08x\n", status); } RevertToSelf(); } else PRINT_ERROR_AUTO("SetThreadToken"); CloseHandle(hNewToken); } else PRINT_ERROR_AUTO("DuplicateTokenEx"); CloseHandle(hToken); } else PRINT_ERROR_AUTO("OpenProcessToken"); TerminateProcess(processInfos.hProcess, 0); CloseHandle(processInfos.hProcess); CloseHandle(processInfos.hThread); } else PRINT_ERROR_AUTO("CreateProcessWithLogonW"); RtlFreeUnicodeString(&uProg); } RtlFreeUnicodeString(&uPass); } RtlFreeUnicodeString(&uDomain); } RtlFreeUnicodeString(&uKdc); } RtlFreeUnicodeString(&uUser); } }
NTSTATUS kuhl_m_net_user(int argc, wchar_t * argv[]) { NTSTATUS status, enumDomainStatus, enumUserStatus; UNICODE_STRING serverName, *groupName; SAMPR_HANDLE hServerHandle, hBuiltinHandle = NULL, hDomainHandle, hUserHandle; DWORD domainEnumerationContext, domainCountRetourned, userEnumerationContext, userCountRetourned, groupsCountRetourned, i, j, k, *usage, aliasCountRetourned, *alias; PSAMPR_RID_ENUMERATION pEnumDomainBuffer, pEnumUsersBuffer; PSID domainSid, userSid; PGROUP_MEMBERSHIP pGroupMemberShip; SID builtin = {1, 1, {0, 0, 0, 0, 0, 5}, {32}}; RtlInitUnicodeString(&serverName, argc ? argv[0] : L""); status = SamConnect(&serverName, &hServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_ENUMERATE_DOMAINS | SAM_SERVER_LOOKUP_DOMAIN, FALSE); if(NT_SUCCESS(status)) { status = SamOpenDomain(hServerHandle, DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP, &builtin, &hBuiltinHandle); if(!NT_SUCCESS(status)) PRINT_ERROR(L"SamOpenDomain Builtin (?) %08x\n", status); domainEnumerationContext = 0; do { enumDomainStatus = SamEnumerateDomainsInSamServer(hServerHandle, &domainEnumerationContext, &pEnumDomainBuffer, 1, &domainCountRetourned); if(NT_SUCCESS(enumDomainStatus) || enumDomainStatus == STATUS_MORE_ENTRIES) { for(i = 0; i < domainCountRetourned; i++) { kprintf(L"\nDomain name : %wZ", &pEnumDomainBuffer[i].Name); status = SamLookupDomainInSamServer(hServerHandle, &pEnumDomainBuffer[i].Name, &domainSid); if(NT_SUCCESS(status)) { kprintf(L"\nDomain SID : "); kull_m_string_displaySID(domainSid); status = SamOpenDomain(hServerHandle, DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP, domainSid, &hDomainHandle); if(NT_SUCCESS(status)) { userEnumerationContext = 0; do { enumUserStatus = SamEnumerateUsersInDomain(hDomainHandle, &userEnumerationContext, 0/*UF_NORMAL_ACCOUNT*/, &pEnumUsersBuffer, 1, &userCountRetourned); if(NT_SUCCESS(enumUserStatus) || enumUserStatus == STATUS_MORE_ENTRIES) { for(j = 0; j < userCountRetourned; j++) { kprintf(L"\n %-5u %wZ", pEnumUsersBuffer[j].RelativeId, &pEnumUsersBuffer[j].Name); status = SamOpenUser(hDomainHandle, USER_READ_GROUP_INFORMATION | USER_LIST_GROUPS | USER_READ_ACCOUNT | USER_READ_LOGON | USER_READ_PREFERENCES | USER_READ_GENERAL, pEnumUsersBuffer[j].RelativeId, &hUserHandle); if(NT_SUCCESS(status)) { status = SamGetGroupsForUser(hUserHandle, &pGroupMemberShip, &groupsCountRetourned); if(NT_SUCCESS(status)) { for(k = 0; k < groupsCountRetourned; k++) { kprintf(L"\n | %-5u ", pGroupMemberShip[k].RelativeId); status = SamLookupIdsInDomain(hDomainHandle, 1, &pGroupMemberShip[k].RelativeId, &groupName, &usage); if(NT_SUCCESS(status)) { kprintf(L"%wZ", groupName); SamFreeMemory(groupName); SamFreeMemory(usage); } else PRINT_ERROR(L"SamLookupIdsInDomain %08x", status); } SamFreeMemory(pGroupMemberShip); } else PRINT_ERROR(L"SamGetGroupsForUser %08x", status); status = SamRidToSid(hUserHandle, pEnumUsersBuffer[j].RelativeId, &userSid); if(NT_SUCCESS(status)) { status = SamGetAliasMembership(hDomainHandle, 1, &userSid, &aliasCountRetourned, &alias); if(NT_SUCCESS(status)) { for(k = 0; k < aliasCountRetourned; k++) { kprintf(L"\n |`%-5u ", alias[k]); status = SamLookupIdsInDomain(hDomainHandle, 1, &alias[k], &groupName, &usage); if(NT_SUCCESS(status)) { kprintf(L"%wZ", groupName); SamFreeMemory(groupName); SamFreeMemory(usage); } else PRINT_ERROR(L"SamLookupIdsInDomain %08x", status); } SamFreeMemory(alias); } else PRINT_ERROR(L"SamGetAliasMembership %08x", status); if(hBuiltinHandle) { status = SamGetAliasMembership(hBuiltinHandle, 1, &userSid, &aliasCountRetourned, &alias); if(NT_SUCCESS(status)) { for(k = 0; k < aliasCountRetourned; k++) { kprintf(L"\n |´%-5u ", alias[k]); status = SamLookupIdsInDomain(hBuiltinHandle, 1, &alias[k], &groupName, &usage); if(NT_SUCCESS(status)) { kprintf(L"%wZ", groupName); SamFreeMemory(groupName); SamFreeMemory(usage); } else PRINT_ERROR(L"SamLookupIdsInDomain %08x", status); } SamFreeMemory(alias); } else PRINT_ERROR(L"SamGetAliasMembership %08x", status); } SamFreeMemory(userSid); } else PRINT_ERROR(L"SamRidToSid %08x", status); } else PRINT_ERROR(L"SamOpenUser %08x", status); } SamFreeMemory(pEnumUsersBuffer); } else PRINT_ERROR(L"SamEnumerateUsersInDomain %08x", enumUserStatus); } while(enumUserStatus == STATUS_MORE_ENTRIES); SamCloseHandle(hDomainHandle); } else PRINT_ERROR(L"SamOpenDomain %08x", status); SamFreeMemory(domainSid); } else PRINT_ERROR(L"SamLookupDomainInSamServer %08x", status); } SamFreeMemory(pEnumDomainBuffer); } else PRINT_ERROR(L"SamEnumerateDomainsInSamServer %08x\n", enumDomainStatus); kprintf(L"\n"); } while(enumDomainStatus == STATUS_MORE_ENTRIES); if(hBuiltinHandle) SamCloseHandle(hBuiltinHandle); SamCloseHandle(hServerHandle); } else PRINT_ERROR(L"SamConnect %08x\n", status); return ERROR_SUCCESS; }