Service Account服务账户之用LocalSystem枚举HKEY_Local_MACHINE\SECURITY下面的子键

来源:互联网 发布:关闭百度搜索合作网络 编辑:程序博客网 时间:2024/05/17 04:35

之前在看Windows Internals这本书的时候,在windows安全机制那一章节时遇见了一个如标题说明相似的问题,一直困扰着我,当时并没有解决,放在那儿,

当时我的做法是

1.管理员打开cmd窗口,输入并运行regedt32.exe,打开注册表了

2.找到HKEY_Local_MACHINE\SECURITY子键,当时一阵小乐乎,因为发现"新东西" 了嘛,可是接着就是一阵冷水,这个子键下面既没有发现键值项,也没发现子子键,心中暗道,我靠,怎么啥东西都没有呢,是哪里搞错了?心里火急火急的又去翻阅书,看着书里写的煞有其事,我这里却什么都没有,当时心里简直是心如火燎啊,一万匹草泥马奔腾...

3.开始查百度,什么的,我靠,当时大概的映象是好像没有发现什么有用的东西,越搜越烦,越搜越心冷,然后就让它去吧~,以我的小经验来看,这玩意,除非后来,偶遇你缺失的某部分所需的资料,又或是除非有人指点你,大概你与它无缘了吧,先放吧,pass...


于是就有了这一文了,

论这个小发现,还是源于自己在msdn上慢慢的查询得来,当时不是搜索查询了,只是当时自己在msdn中研究Sid,账户,ACL,Token,Destop,Winstasion,session,安全相关方面时的偶然所得,当然,本文需要的还有服务方面,注册表方面的知识了..


上正文:

1,msdn首发网页,地址如下:

                                                         Service User Accounts

里面其他都先不说,因为我还没研究过,理由很简单,没有遇见这方面的问题故而没有动机,而且暂时没有时间,看看以后能否遇见这些概念对应的问题,那时再去深入研究它们,现在我只关注很少

图1.


上段说明,如果你在CreateService或者ChangeServiceConfig函数中使用LocalSystem 账户,任何输入密码将被忽略

图2


 上段说明,LocalSystem账户是一个被Service Control Manager预置的账户,(暂时忽略其他内容)

图3


上段说明 服务可以打开HKEY_LOCAL_MACHINE\SERCURITY子键


 2.准备一个服务以及安装服务的程序,我这里贴了个我自己从自己代码片段抽出来的程序段,自己写的时候没怎么注意格式排版,就是怎么简单无脑怎么来.....

这些代码你都可以从网上搜的出来....

2.1 服务安装程序

#include "stdafx.h"#include<windows.h>#include <locale.h>VOID SvcInstall( );int _tmain(int argc,_TCHAR* argv[]){SvcInstall( );return 0;}VOID SvcInstall( ){SC_HANDLE schSCManager;SC_HANDLE schService;TCHAR szPath[MAX_PATH] = {0};TCHAR szSvcName[MAX_PATH] = {0};setlocale(LC_ALL,"");wscanf_s(TEXT("%s"),szSvcName,MAX_PATH);//输入服务名wscanf_s(TEXT("%s"),szPath,MAX_PATH);<span style="white-space:pre"></span>//输入服务程序可执行文件路径schSCManager = OpenSCManager(<span style="white-space:pre"></span>//准备SCMNULL,NULL,SC_MANAGER_ALL_ACCESS);if(NULL == schSCManager){_tprintf(TEXT("OpenSCManager failed (%d)\n"),GetLastError( ));return ;}schService = CreateService(<span style="white-space:pre"></span>//创建服务schSCManager,szSvcName,szSvcName,SERVICE_ALL_ACCESS,SERVICE_WIN32_OWN_PROCESS,SERVICE_DEMAND_START,SERVICE_ERROR_NORMAL,szPath,NULL,NULL,NULL,NULL,//<span style="color: rgb(69, 69, 69); font-family: 'Segoe UI', 'Lucida Grande', Verdana, Arial, Helvetica, sans-serif; font-size: 14px; line-height: 20.006px;">lpServiceStartName</span><span style="color: rgb(69, 69, 69); font-family: 'Segoe UI', 'Lucida Grande', Verdana, Arial, Helvetica, sans-serif; font-size: 14px; line-height: 20.006px;"> [in, optional],如果是NULL,使用的就是LocalSystem账户,来源于msdn 该api文档说明</span>NULL);if(NULL == schService){_tprintf(TEXT("CreateService failed (%d)\n"),GetLastError);CloseServiceHandle(schSCManager);return ;}else_tprintf(TEXT("Service installed successfully\n"));CloseServiceHandle(schService);CloseServiceHandle(schSCManager);}
1.以上单独生成一个可执行文件,运行,输入你自己定义的服务名称,我这人用的是连续的英文字符串,中文没有试过, 

2.然后输入服务程序可执行文件路径名,注意了不是这段代码生成的exe文件,这个只是用来安装服务程序的,而是下面的程序生成的文件路径,那才是真正的服务程序


2.2

// ConsoleApplication3.cpp : 定义控制台应用程序的入口点。// 创建服务程序.cpp : 定义控制台应用程序的入口点。#include "stdafx.h"#include<windows.h>#include <Strsafe.h>#include <locale.h>#define SLEEP_TIME 5000#define FILE_PATH "D:\\log.txt"BOOL bRun = FALSE;SERVICE_STATUS servicestatus;SERVICE_STATUS_HANDLE hstatus;#define MAX_KEY_LENGTH 255#define MAX_VALUE_NAME 16383TCHAR* DwordToPTSTR(DWORD type){switch(type){case REG_NONE:return TEXT("REG_NONE");case REG_SZ:return TEXT("REG_SZ");case REG_EXPAND_SZ:return TEXT("REG_EXPAND_SZ");case REG_BINARY:return TEXT("REG_BINARY");case REG_DWORD:return TEXT("REG_DWORD");case REG_DWORD_BIG_ENDIAN:return TEXT("REG_DWORD_BIG_ENDIAN");case REG_LINK:return TEXT("REG_LINK");case REG_MULTI_SZ:return TEXT("REG_MULTI_SZ");case REG_RESOURCE_LIST:return TEXT("REG_RESOURCE_LIST");case REG_FULL_RESOURCE_DESCRIPTOR:return TEXT("REG_FULL_RESOURCE_DESCRIPTOR");case REG_RESOURCE_REQUIREMENTS_LIST:return TEXT("REG_RESOURCE_REQUIREMENTS_LIST");case REG_QWORD:return TEXT("REG_QWORD");}return NULL;}void QueryKey(HKEY hKey){TCHAR achKey[MAX_KEY_LENGTH];//buffer for subkey nameDWORD cbName;//size of name stringTCHAR achClass[MAX_PATH] = TEXT("");//buffer for class nameDWORD cchClassName = MAX_PATH;//size of class stringDWORD cSubKeys = 0;//number of subkeysDWORD cbMaxSubkey;//longest subkey sizeDWORD cchMaxClass;//longest class stringDWORD cValues;//number of values for keyDWORD cchMaxValue;//longest value nameDWORD cbMaxValueData;//longest value dataDWORD cbSecurityDescriptor;//size of security descriptorFILETIME ftLastWriteTime;//last write timeDWORD i,retCode;TCHAR achValue[MAX_VALUE_NAME];DWORD cchValue = MAX_VALUE_NAME;setlocale(LC_ALL,"Chinese-simplified");//Get the class name and the value countretCode = RegQueryInfoKey(hKey,//key handle要被查询信息的子键的句柄achClass,//buffer for class name存放子键类别字符串的缓冲区&cchClassName,//size of class string存放子键类别字符串缓冲区的大小NULL,//reserved保留字段&cSubKeys,//number of subkeys要被查询信息的子键的子键数量&cbMaxSubkey,//longest subkey size要被查询信息的子键的子键中键名称字符串最大的长度 (以字符为单位)&cchMaxClass,//longest class string要被查询信息的子键的子键中类别名称字符串最大的长度 (以字符为单位)&cValues,//number of values for this key要被查询信息的子键的键值项的数量 &cchMaxValue,//longest value name要被查询信息的子键的所有键值项名称字符串最大的长度  (以字符为单位)&cbMaxValueData,//longest value data要被查询信息的子键的所有键值项数据字符串最大的长度 (以字符为单位)&cbSecurityDescriptor,//security descriptor要被查询信息的子键的安全描述符的大小(以字节为单位)&ftLastWriteTime//last write time);//===================================================================================FILETIME localFileTime = {0};SYSTEMTIME sysTime = {0};FileTimeToLocalFileTime(&ftLastWriteTime,&localFileTime);FileTimeToSystemTime(&localFileTime,&sysTime);TCHAR temp[1024] = {0};wsprintf(temp, TEXT("this key last write time : %d年%d月%d日%d时%d分\n"), sysTime.wYear,sysTime.wMonth,sysTime.wDay,sysTime.wHour,sysTime.wSecond);OutputDebugStringW(temp);//=====================================================================================TCHAR* classStr = new TCHAR[cbMaxSubkey];//Enumerate the subkeys ,until RegEnumKeyEx failsif(cSubKeys){TCHAR temp[1024] = {0};wsprintf(temp,TEXT("\nNumber of subkeys:%d\n"),cSubKeys);OutputDebugStringW(temp);for(i = 0; i < cSubKeys; i++){cbName = MAX_KEY_LENGTH;//每用完一次要重新设定该值DWORD maxSubKey = cbMaxSubkey;wmemset(classStr,0,cbMaxSubkey);retCode = RegEnumKeyEx(hKey,i,achKey,&cbName,NULL,classStr,&maxSubKey,&ftLastWriteTime);if(retCode == ERROR_SUCCESS){TCHAR temp1[1024] = {0};wsprintf(temp1,TEXT("(%d) %s 子键\n"),(i+1),achKey);OutputDebugStringW(temp1);//输出子键名}}}delete[]classStr;if(cValues){TCHAR temp[1024] = {0};wsprintf(temp,TEXT("\nNumber of values: %d\n"),cValues);OutputDebugStringW(temp);for(i = 0,retCode = ERROR_SUCCESS; i < cValues; i++){cchValue = MAX_VALUE_NAME;//每用完一次要重新设定该值DWORD type = 0;retCode = RegEnumValue(hKey,i,achValue,&cchValue,NULL,&type,NULL,NULL);if(retCode == ERROR_SUCCESS){TCHAR temp1[1024] = {0};wsprintf(temp1,TEXT("[%d] %s 类型:%s\n"),achValue,DwordToPTSTR(type));OutputDebugStringW(temp1);//输出键值类型名}}}}VOID WINAPI CtrlHandler(DWORD request){switch(request){case SERVICE_CONTROL_STOP:bRun = FALSE;servicestatus.dwCurrentState = SERVICE_STOPPED;break;case SERVICE_CONTROL_SHUTDOWN:bRun = FALSE;servicestatus.dwCurrentState = SERVICE_STOPPED;break;default:break;}SetServiceStatus(hstatus,&servicestatus);}VOID WINAPI ServiceMain(DWORD dwNumServicesArgs,LPTSTR* lpServicecArgVectors){servicestatus.dwServiceType = SERVICE_WIN32;servicestatus.dwCurrentState = SERVICE_START_PENDING;servicestatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP;servicestatus.dwWin32ExitCode = 0;servicestatus.dwServiceSpecificExitCode = 0;servicestatus.dwWaitHint = 0;//SetServiceStatus(hstatus,&servicestatus);hstatus = RegisterServiceCtrlHandler(TEXT("testservice"),CtrlHandler);if(hstatus == 0){MessageBox(0,TEXT("ERROR"),0,0);return ;}servicestatus.dwCurrentState = SERVICE_RUNNING;SetServiceStatus(hstatus,&servicestatus);bRun = TRUE;HKEY hTestKey;if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SECURITY"),0,KEY_READ,&hTestKey) == ERROR_SUCCESS){QueryKey(hTestKey);}RegCloseKey(hTestKey);}int _tmain(int argc,_TCHAR* argv[]){SERVICE_TABLE_ENTRY entrytable[2] = {{TEXT("testesrvice"),(LPSERVICE_MAIN_FUNCTION)ServiceMain},{0,0}};BOOL success = StartServiceCtrlDispatcher(entrytable);if(success)MessageBox(0,TEXT("TRUE"),0,0);elseMessageBox(0,TEXT("FALSE"),0,0);return 0;}

以上又可以生成一个exe可执行文件,这才是真正的服务主程序,前面的是一个用来安装服务的程序,


至此我们有了两个程序了,一个服务主程序,一个安装服务的程序

还需要准备一下工具 cmd窗口中输入的sc.exe,  

Advanced Windows Service Manager.exe(用来查看服务),

Dbgview.exe(查看服务主程序中的输出字符串,这里用MessageBox不可行,我估计跟交互式服务有关,MessageBox毕竟是窗口的一种,详情这里不究)


3,GO,GO,GO

3.1运行安装服务的程序,

输入testservice (这是我这儿的服务名),

回车,

接着在输入路径E:\DDDDDDDebug\ConsoleApplication1\Debug\ConsoleApplication3.exe  (ConsoleApplication3.exe是我的服务主程序,也就是用来被安装的服务);

贴图如下:

右键点击Advanced Windows Service Manager .exe,如下选择



3.2管理员权限运行

Dbgview.exe

capture选项卡,选中Capture Win32,Capture GlobalWin32,Capture Events


未安装之前

Advanced Windows Service Manager.exe主界面未有相应服务名

安装之后


这时已经安装,但是未运行

3.3运行cmd,输入sc start testservice,回车





DbgView.exe中显示



对比下至此,是不是比管理员直接打开注册表去查看,多了几分继续研究下去的希望呢?


0 0
原创粉丝点击