




已阅读5页,还剩24页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
检测并禁用隐藏服务隐藏服务的概念是由hxdef 和rootkit这些后门工具提出的。这些后门工具通过挂钩系统本地调用来隐藏自己,原本通过调用Windows API调用查看系统服务的企图都是徒劳的。所以这时的系统是不可靠的,不值得信任的。目前针对查找隐藏服务的工具已经有很多,比如IceSword,knlsc,FHS等等。虽然这些软件都是免费的,但是它们到目前为止都不是开源,所以将自己的实现版本展示出来,正如knlsc的作者所说的那样,这是一个简单的小程序。Knlsc是通过将%SystemRoot%/System32/Config/System这个Hive文件转储出来,提取出ControlSet001/Services的子项再与RegEnumKeyEx的输出结果进行比对,发现若是在RegEnumKeyEx的输出结果中没有的子项就可以认为是一个隐藏的服务。当然knlsc还认为隐藏服务必须同时拥有ImagePath,Start,Type三个键值。据说knlsc运行时还将从资源段中放出一个驱动程序,但是估计这个驱动是假的。将knlsc托壳后用VC从资源段中导出的文件是一个没有EntryPoint但有MZ标志的驱动,没有办法进行反汇编。或许作者使用了SMC技术,放出资源文件后在进行修改,在执行文件中也有NtLoadDriver的调用片段,但是同一作者的knlps中的资源驱动却未作任何的处理。要实现检测隐藏服务的功能其实没有必要使用驱动程序,即使可以验证knlsc驱动的真实性。直接对Hive文件的转储也不是必须的,虽然这只要通过修改Gary Nebbett的示例代码就可做到。Hive文件的转储可以通过RegSaveKey函数来进行,rootkitrevealer就是使用这个API的扩充函数RegSaveKeyEx工作的,至少到目前为止还没有挂钩这类函数的后门,但是世上没有永远的安全,在理论上是可行的,可能不得不对该函数的输出文件进行处理,这将在一定程度上影响该函数的执行时间。使用该函数时还必须赋予调用进程以SE_BACKUP_NAME权限。在实现中将“HKEY_LOCAL_MACHINESYSTEMControlSet001Services的子项都转储为Hive格式文件(使用DumpServiceInfo函数),存放在C:tmp.hive,在盘下不可有同名文件,否则会发生Dump错误。现在的问题是如何对Hive格式文件进行处理,在这一点上必须感谢Petter Nordahl-Hagen所写的NT Registry Hive access library,它是The Offline NT Password Editor的一部分。本人的实现很大程度上就是参照他的程序,然而这个库工作在Linux环境,但是它向VC编译器移植的工作量是极少的,只需稍加修改。将#include 去掉将程序中三处的#define D_OFFS(o) ( (void *)&(key-o)-(void *)hdesc-buffer-vofs )改为#define D_OFFS(o) ( (int *)&(key-o)-(int *)hdesc-buffer-vofs )因为在中无法打印void * 类型,只得改为int *。将程序中唯一的一处使用snprintf函数该为_snprintf,即snprintf(path,maxlen,(.)%s,tmp);改为_snprintf(ptth,maxlen,”()%s”,tmp);添加两个不支持的函数来使编译通过void bzero(void *s,int n)memset(s,0,n);int strncasecmp(const char *s1, const char *s2, size_t n)return _stricmp(s1,s2);为了表示对Petter Nordahl-Hagen的尊重,我不再修改他的库文件ntreg.c和ntreg.h(除了以上移植的需要),而是将所有需要重写和添加的函数放到KHS.C文件中,这样可以使原来的库文件保持其独立性。由于在Petter库中openHive函数使用open 和 read 函数来进行hive文件的读取,在VC条件下的read函数有一个问题,每当文件中存在一个0x1a的二进制数值时,read函数就会在那儿终止,这样就会导致hive文件无法完全导入。所以就使用了Windows API重写openHive,命名为My_openHive。相应的还重写了closeHive,writeHive并加上了前缀My_。随后GetPatterns函数将使用RegEnumKey枚举的服务键值名称保存在pattern的全局变量指针中,为以后的匹配作准备。ShowHideService函数是由nk_ls函数改写的,将由Hive文件导出的buffer中的服务名称与patternI作比较,这个比较过程使用CompareHive函数。若比较结果为相同,CompareHive会将patternI置为NULL,以提高匹配速度,或许有更好的匹配算法,但在这个小程序中也不使用了。若结果不同,则说明该服务是隐藏的,显示出该隐藏服务的名称,文件路径(ShowPathImage是由cat_vk改写的),启动类型和服务类型,并将该隐藏服务的启动类型改为SERVICE_DISABLED。如果存在隐藏服务并且禁止了该隐藏服务(仅在buffer中的修改),通过调用My_writeHive将修改过的hive 的buffer保存在C:tmp2.hiv文件中,此时提供用户一个选择“是否要禁用隐藏服务”,默认的选择是“否”,如果用户确实想要禁用,可输入“Yes”或“,接着使用RestoreServiceInfo函数将C:tmp2.hiv文件导回原来的%SystemRoot%/System32/Config/System这个Hive文件中,这一步由系统自己来完成,值得一提的是Win32函数RegRestoreKey即使在dwFlags参数中使用了REG_FORCE_RESTORE (8) ,在第一次调用时往往会错误返回,一般在第二次调用就会成功,所以就使用了一个循环直到它成功后为止,并且调用它的进程需要有SE_RESTORE_NAME的权限。至于让隐藏服务真正失去作用,仍然需要重新启动计算机之后。下面给出KHS.C的完整源代码:/* KHS.cpp - Kill Hide Services v0.1* Copyright (c) 2005 linux2linux.* It takes notes from knlsc and FHS.* Thank you, Petter Nordahl-Hagen, for your NT Registry Hive access library* Freely distributable in source or binary for noncommercial purposes.* THIS SOFTWARE IS PROVIDED BY PETTER NORDAHL-HAGEN AS IS AND* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE* ARE DISCLAIMED.IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF* SUCH DAMAGE.*/#include ntreg.h#include char *pattern;int pattern_count;int nohideservice;int ischange;extern char *val_typesREG_MAX+1;struct hive *My_openHive(char *filename, int mode);void My_closeHive(struct hive *hdesc);int CompareHive(char *sample)int i;for(i = 0; i filename = str_dup(filename);hdesc-state = 0;hdesc-size = 0;hdesc-buffer = NULL;hFile = CreateFile(hdesc-filename,GENERIC_READ, / open for reading0,/ do not shareNULL, / no securityOPEN_ALWAYS,/ existing file onlyFILE_ATTRIBUTE_NORMAL,/ normal fileNULL); / no attr. templateif (hFile = INVALID_HANDLE_VALUE)printf(Could not open hive file.);/ process errorreturn 0;/* Read the whole file */hdesc-size = GetFileSize(hFile,NULL);ALLOC(hdesc-buffer,1,hdesc-size);ReadFile(hFile, (void *)hdesc-buffer, hdesc-size, &szread, NULL);CloseHandle(hFile);if (szread size) printf(Could not read file, got %d bytes while expecting %dn,szread, hdesc-size);My_closeHive(hdesc);return(NULL);/* Now run through file, tallying all pages */* NOTE/KLUDGE: Assume first page starts at offset 0x1000 */ pofs = 0x1000; hdr = (struct regf_header *)hdesc-buffer; if (hdr-id != 0x66676572) printf(openHive(%s): File does not seem to be a registry hive!n,filename); return(hdesc); for (c = hdr-name; *c & (c name + 64); c += 2) putchar(*c); hdesc-rootofs = hdr-ofs_rootkey + 0x1000; while (pofs size) #ifdef LOAD_DEBUGif (verbose) hexdump(hdesc-buffer,pofs,pofs+0x20,1);#endif p = (struct hbin_page *)(hdesc-buffer + pofs); if (p-id != 0x6E696268) printf(Page at 0x%lx is not hbin, assuming file contains garbage at end,pofs); break; hdesc-pages+;#ifdef LOAD_DEBUG if (verbose) printf(n# Page at 0x%0lx has size 0x%0lx, next at 0x%0lx #n,pofs,p-len_page,p-ofs_next);#endif if (p-ofs_next = 0) #ifdef LOAD_DEBUG if (verbose) printf(openhive debug: bailing out. pagesize zero!n);#endif return(hdesc); #if 0 if (p-len_page != p-ofs_next) #ifdef LOAD_DEBUG if (verbose) printf(openhive debug: len & ofs not same. HASTA!n);#endif exit(0); #endif vofs = pofs + 0x20; /* Skip page header */#if 1 while (vofs-pofs ofs_next) vofs += parse_block(hdesc,vofs,verbose); #endif pofs += p-ofs_next; return(hdesc);void My_closeHive(struct hive *hdesc)FREE(hdesc-filename);FREE(hdesc-buffer);FREE(hdesc);int My_writeHive(struct hive *hdesc)HANDLE hFile;DWORD dwBytesWritten;hFile = CreateFile(C:tmp2.hiv,GENERIC_WRITE,/ open for writing0,/ do not shareNULL, / no securityCREATE_ALWAYS,/ open or createFILE_ATTRIBUTE_NORMAL,/ normal fileNULL);if(hFile = INVALID_HANDLE_VALUE)printf(Cant open dump file); return 0;WriteFile(hFile, hdesc-buffer, hdesc-size,&dwBytesWritten, NULL);if(dwBytesWritten != hdesc-size)printf(WriteHive errorn);CloseHandle(hFile);return 0;void CleanPatterns()int i;if(pattern!=NULL) for(i = 0; i pattern_count; i+) if(patterni!=NULL)free(patterni); free(pattern);void GetPatterns()HANDLE hService;CHAR achKeyMAX_PATH;DWORD i;DWORD retCode;int Nohide = 1;DWORD SubKeyNum = 0;pattern_count = 0;if(RegOpenKeyEx( HKEY_LOCAL_MACHINE, / handle to open key SYSTEMControlSet001Services, / subkey name NULL, / reserved KEY_ALL_ACCESS,/ security access mask &hService/ handle to open key ) != ERROR_SUCCESS) printf(sorry %dn,GetLastError(); return;RegQueryInfoKey( hService,NULL,NULL,NULL,&SubKeyNum,NULL,NULL,NULL,NULL,NULL,NULL,NULL);/Before it dont work well , because i set the wrong premission of HKEY/KEY_ALL_ACCESS is neededif(SubKeyNum = 0) printf(SubKeys Number is NULL, its too strange.n); return;pattern = malloc(sizeof(char *) * SubKeyNum );for (i = 0, retCode = ERROR_SUCCESS; retCode = ERROR_SUCCESS; i+)retCode = RegEnumKey( hService,/ handle to key to query i,/ index of subkey to query achKey,/ buffer for subkey name MAX_PATH / size of subkey name buffer );if (retCode = (DWORD)ERROR_SUCCESS)/What i add to get pattern Services Table.pattern pattern_count = strdup ( achKey ) ;pattern_count+; CloseHandle(hService);void ShowPathImage(struct hive *hdesc, int nkofs, char *path)void *data;int len,i,type;char stringSZ_MAX+1;type = get_val_type(hdesc, nkofs, path);if (type = -1) printf(No such value n,path);return;len = get_val_len(hdesc, nkofs, path);if (!len) printf(Value has zero lengthn,path);return;data = (void *)get_val_data(hdesc, nkofs, path, 0);if (!data) printf(Value references NULL-pointer (bad boy!)n,path);abort();return;switch (type) case REG_SZ:case REG_EXPAND_SZ:case REG_MULTI_SZ:cheap_uni2ascii(data,string,len);for (i = 0; i 1)-1; i+) if (stringi = 0) stringi = n;if (type = REG_SZ) break;puts(string);break;case REG_DWORD:printf(0x%08x,*(unsigned short *)data);break;default:printf(Dont know how to handle type yet!n);case REG_BINARY:hexdump(char *)data, 0, len, 1);void EnablePriv(LPCTSTR lpName)HANDLE hToken;LUID sedebugnameValue;TOKEN_PRIVILEGES tkp;if ( ! OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )printf(open process errorn); return;if ( ! LookupPrivilegeValue( NULL, lpName, &sedebugnameValue ) ) printf(cant find privilege errorn); CloseHandle( hToken ); return;tkp.PrivilegeCount = 1;tkp.Privileges0.Luid = sedebugnameValue;tkp.Privileges0.Attributes = SE_PRIVILEGE_ENABLED;if ( ! AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof (tkp), NULL, NULL ) ) printf(adjust errorn); CloseHandle( hToken );int DumpServiceInfo()HKEY hService;EnablePriv(SE_BACKUP_NAME);if(RegOpenKeyEx( HKEY_LOCAL_MACHINE, / handle to open key SYSTEMControlSet001Services, / subkey name NULL, / reserved KEY_ALL_ACCESS, / security access mask &hService/ handle to open key ) != ERROR_SUCCESS)printf(cant get key handlen); return 0;if(RegSaveKey(hService,C:tmp.hiv,NULL) != ERROR_SUCCESS) printf(Cant dump Service infon); CloseHandle(hService); return 0;CloseHandle(hService);return 1;void ShowHideService(struct hive *hdesc, char *path, int vofs, int type)struct nk_key *key;int nkofs;struct ex_data ex;int count = 0, countri = 0;/wHAT I ADDvoid *data;int nkofs_cat;int serviceno;serviceno = 1;nkofs = trav_path(hdesc, vofs, path, 0);if(!nkofs) printf(nk_ls: Key not foundn,path);abort();return;nkofs += 4;key = (struct nk_key *)(hdesc-buffer + nkofs);if (key-id != 0x6b6e) printf(Error: Not a nk node!n);debugit(hdesc-buffer,hdesc-size); if (key-no_subkeys) while (ex_next_n(hdesc, nkofs, &count, &countri, &ex) 0) if(!CompareHive() ) nohideservice = 0; if(!(serviceno - 1)printf(Hide Service List:n); printf(n%d.-n,serviceno+ ); printf(Hide Service : %sn, ); nkofs_cat = trav_path(hdesc, vofs, , 0); printf(Image Path : ); ShowPathImage(hdesc, nkofs_cat + 4, ImagePath); data = (void *) get_val_data(hdesc, nkofs_cat + 4, Start, 0 ); if( data != NULL) printf(Start Type : );switch(*(unsigned short *)data) case 0:printf(SERVICE_BOOT_START);break;case 1:printf(SERVICE_SYSTEM_START);break;case 2:printf(SERVICE_AUTO_START);break;case 3:printf(SERVICE_DEMAND_START);break;case 4:printf(SERVICE_DISABLED);break;default:printf(UNKOWN START TYPE);/disable the serviceif( *(unsigned short *)data != 4 )printf(Will be set to Disabled);put_dword(hdesc, nkofs_cat + 4, Start, 4);ischange = 1;printf(n); data = (void *) get_val_data(hdesc, nkofs_cat + 4, Type, 0 ); printf(Service Type : ); if( data != NULL) if(*(unsigned short *)data & 1) printf(SERVICE_KERNEL_DRIVER );if(*(unsigned short *)data & 2) printf(SERVICE_FILE_SYSTEM_DRIVER );if(*(unsigned short *)data & 8)printf(SERVICE_RECOGNIZER_DRIVER );if(*(unsigned short *)data & 16)printf(SER
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 长期卧床病人并发症的护理
- 新能源技术研究岗位实习周记原创范文
- 特效制作团队的职位及其职责概览
- 2024年张掖市临泽县三支一扶笔试真题
- 知识缺乏的护理诊断及措施
- 玄武岩纤维项目可行性研究报告范文
- 高考英语作文常见错误与改进范文
- 2025年中国混泥土泵项目投资计划书
- 幼儿园大班科学《认识茶叶》课件
- 2025初中学校学科竞赛组织计划
- 北师大版五年级(下册)数学知识要点归纳|期末复习
- 口腔种植修复(基础篇)知到章节答案智慧树2023年浙江大学
- 同济大学实验报告封面
- 2023年开放大学应急管理记分作业题库
- 检针机九点测试方法示意图
- 马鞍山南山开发公司和尚桥铁矿围岩综合利用扩能技术改造项目环境影响报告表
- 公司吊具点检表
- 知识点一RLC串联电路的电压关系
- 宁夏物理中考考点
- 门诊病历检查评分表
- NY 529-2002兽医注射针
评论
0/150
提交评论