wocaca
入侵后第一步做什么?当然是查看肉鸡的各种系统信息,然后再决定这个肉鸡该吃还是该丢?是好鸡还是病鸡?那检测肉鸡系统信息的方法是什么呢?全手工?累!用大程序?不方便传输!该怎么办呢?还是发扬我们的diy精神,自己打造一个适合自己使用习惯的系统信息检测工具吧!follow me!1.操作系统详细信息收集我们一般所讲的系统信息包含操作系统版本、service pack、build号等,如何编程得到这些信息?我们就要用到GetVersionEx(LPOSVERSIONINFO lpVersionInfo)这个API函数了!这个函数在很多场合已经被提到多次,很多朋友都知道,但是知道这个函数并不能很好的运用它是可惜的,它的参数是个复杂的OSVERSIONINFO结构,而且更复杂的是,获得这个结构以后,我们该怎样根据这个结构来判断操作系统类型?由于Windows家族版本众多,要理清这里面错综复杂的关系还真不是一件容易的事。Msdn上恰好有这样的例子,我对这个例子进行仔细分析后,再对部分代码进行了修改,使之能符合我们程序的要求。最后把这个功能封装成一个函数,以方便以后使用。(“得到肉鸡操作系统信息”函数见光盘)这个函数比较长,检测的系统比较多,有些系统我们现在很少遇到了。这个函数的作用就是直接输出操作系统版本、Service Pack版本和Build号。在电脑上的运行结果为:OS: Microsoft Windows XP Professional (Build2600)2.运行时间收集 肉鸡是不是经常维护、管理是我们判断一个服务器是不是好肉鸡的一大重要标准,试想:如果一个服务器五年都不重新启动一次,那它还有什么安全性可言呢?当然,遇到这样的肉鸡可是上辈子修来的福分 :) !Microsoft正好给我们提供了一个GetTickCount()函数,这个函数能返回从开机到现在的运行时间,以毫秒计。不过有一点需要注意:由于这个函数返回的是DWORD类型的值,因此最多能检测到的运行时间是49.7天(这对于普通的肉鸡来说时间已经够了)。//得到运行时间void GetRunningTime(){DWORD dwTime;int nDay,nHour,nMinute;dwTime = GetTickCount();nMinute = dwTime / 60000;nHour = nMinute / 60;nMinute = nMinute - nHour * 60;nDay = nHour / 24;printf("Running Time: ");printf("%d day(s),",nDay);printf("%d hour(s),",nHour);printf("%d minute(s)",nMinute);printf("/n");}成功编译运行后,在电脑上的输出结果为:Running Time: 0 day(s),0 hour(s),18 minute(s)这样是不是很方便呢?3.主机名和当前用户名收集 这个服务器的主机名是什么?上面有那些用户?当前用户是什么?这些都是相当重要的信息,说不定这个服务器就是什么FBI的服务器呢!Microsoft提供的函数GetComputerName()和GetUserName()能很方便地达到这个目的。这两个函数的原型为:BOOL GetComputerName(LPTSTR lpBuffer, LPDWORD lpnSize);其中lpBuffer是返回主机名缓冲区的地址,lpnSize是指向缓冲区大小的指针。BOOL GetUserName(LPTSTR lpBuffer, LPDWORD nSize);其中lpBuffer是返回当前用户名的缓冲区地址,nSize也是指向缓冲区大小的指针。具体程序如下://得到计算机名void GetMyComputerName(){LPTSTR lpszName;DWORD dwSize = 1024;TCHAR tchBuffer[1024];lpszName = tchBuffer;GetComputerName(lpszName,&dwSize);//得到主机名printf("Computer Name: ");printf("%s",lpszName);printf("/n");}//得到当前用户名void GetCurrentUser(){LPTSTR lpszName;DWORD dwSize = 1024;TCHAR tchBuffer[1024];lpszName = tchBuffer;GetUserName(lpszName,&dwSize);//得到当前用户名printf("Current User: ");printf("%s",lpszName);printf("/n");}这两个函数很简单,在电脑上输出结果为:Computer Name: SKYCurrent User: SKYMAN4.系统文件夹路径收集如果我们是用IPC管道来向肉鸡传送文件,然后再登陆上肉鸡,这时候我们就需要知道到什么地方去找那些刚传上来的文件。一般来说,文件是copy到Admin$/system32下面的,而你想过Admin$代表什么没有?下面这个函数可以给你答案://得到系统目录void GetMySystemDirectory(){LPTSTR lpszName;DWORD dwSize = MAX_PATH + 1;TCHAR tchBuffer[MAX_PATH];lpszName = tchBuffer;GetSystemDirectory(lpszName,dwSize);printf("System Directory: ");printf("%s",lpszName);printf("/n");}这里用到了GetSystemDirectory()这个API函数。这个函数的原型为:UINT GetSystemDirectory(LPTSTR lpBuffer, UINT uSize);其中lpBuffer是返回系统文件夹的缓冲区地址,uSize是该缓冲区的大小。系统文件夹有了,Windows文件夹自然也就能得到。不过使用的是另一个API函数:GetWindowsDirectory(),有兴趣的读者可以自己试试。这个函数在电脑上输出结果为:System Directory: D:/WINDOWS/System32(注:我的系统是Win98+WinXP,当前系统是WinXP,系统盘在D盘)5.肉鸡CPU信息收集CPU的重要性不需要我再讲了吧?要是一个肉鸡有4个inter3.2G的cpu……嘿嘿,那可是极品哦!我们知道:在注册表HKEY_LOCAL_MACHINE/Hardware/Description/System/CentralProcessor/0下面有个ProcessorNameString,它的值就是CPU的名字,我们只要把这个值读出来就行了。当然这个值并不是很可靠的,因为可以修改,但是相信很少有人去改它吧?//得到CPU信息void GetCPUInfo(){long lResult;HKEY hKey;TCHAR tchData[64];DWORD dwSize;lResult=RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Hardware//Description//System//CentralProcessor//0",0,KEY_QUERY_VALUE,&hKey);if(lResult == ERROR_SUCCESS){dwSize = sizeof(tchData);RegQueryValueEx(hKey,"ProcessorNameString",NULL,NULL,(LPBYTE)tchData,&dwSize);printf("CPU: ");printf("%s",tchData);}else{printf("CPU: ");printf("Unknown");}RegCloseKey(hKey);printf("/n");}了解这个原理以后,你就可以修改这个值来欺骗别人了。可以手动修改,也可借助工具,比如Windows优化大师。HKEY_LOCAL_MACHINE/Hardware/Description/System/CentralProcessor/0下还有好几个键值与CPU有关,如果你觉得仅仅名字不够详细时,也可以把其它感兴趣的键值一并读出来。在电脑上输出的CPU名字为:CPU: AMD Athlon(TM) XP1800+6.肉鸡内存信息收集Windows系统提供了一个GlobalMemoryStatus()API函数来查询内存状态,利用它就可以很方便地得到物理内存,虚拟内存的当前值。当然在这里我们只需要得到总物理内存和可用内存大小即可。该API函数的原型为:Void GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer);lpBuffer是一个指向MEMORYSTATUS结构的指针。执行GlobalMemoryStatus()函数就可以得到一个MEMORYSTATUS结构,它表示当前内存的状态。下面我们要用到MEMORYSTATUS结构的两个成员:SIZE_T dwTotalPhys;SIZE_T dwAvailPhys;这两个成员从字面上可以了解到前者表示总物理内存,后者表示可用物理内存,但是要注意返回的是以字节为单位的量。//得到内存信息void GetMemoryInfo(){long lVar;MEMORYSTATUS memoryStatus;memset(&memoryStatus, sizeof (MEMORYSTATUS), 0);memoryStatus.dwLength = sizeof (MEMORYSTATUS);GlobalMemoryStatus (&memoryStatus);lVar = memoryStatus.dwTotalPhys / 1024;//转换为KBprintf("Total Memory: ");printf("%ld KB/n",lVar);lVar = memoryStatus.dwAvailPhys / 1024;//转换为KBprintf("Available Memory: ");printf("%ld KB/n",lVar);}输出为以KB为单位的内存大小。在电脑上输出结果为:Total Memory: 261600 KBAvailable Memory: 40336 KB7.肉鸡磁盘信息收集肉鸡硬盘有几个分区?每个分区有多大?剩余空间有多少?能装下多少部电影?能放下多少个论坛?能承受多大的数据?这些都是获得肉鸡后最关心的肉鸡价值问题,如何得到?要达到这个目的要稍微复杂一些:首先我们要调用GetLogicalDriveStrings()这个API函数,目的是想得到一个包含所有磁盘名的字符串,并把各个磁盘名从这个字符串中提取出来。GetLogicalDriveStrings()函数的原型为:DWORD GetLogicalDriveStrings(DWORD nBufferLength, LPTSTR lpBuffer);lpBuffer就是上面提到的那个字符串,nBufferLength是缓冲区的最大值。然后针对每个盘,调用GetDriveType()来判断磁盘类型,比如有固定硬盘分区,光驱,移动分区等。GetDriveType()函数的原型为:UINT GetDriveType(LPCTSTR lpRootPathName);参数lpRootPathName表示目标磁盘的根目录名,比如C:/,这个值从上面函数得到。如果GetDriveType()返回DRIVE_FIXED,就表示这是一个固定硬盘。但是我试了一下,优盘也同样返回DRIVE_FIXED。这时就可以调用GetDiskFreeSpaceEx()来得到该盘的空间信息了。GetDiskFreeSpaceEx()函数原型为:BOOL GetDiskFreeSpaceEx(LPCTSTR lpDirectoryName, PULARGE_INTEGER lpFreeBytesAvailable, PULARGE_INTEGER lpTotalNumberOfBytes, PULARGE_INTEGER lpTotalNumberOfFreeBytes);lpDirectoryName表示目标磁盘的一个目录名,这个值从GetLogicalDriveStrings()返回的字符串中得到。lpFreeBytesAvailable表示目标磁盘上用户线程可用空间,以字节为单位。lpTotalNumberOfBytes表示目标磁盘总大小,以字节为单位。lpTotalNumberOfFreeBytes表示目标磁盘剩余空间大小,以字节为单位。(得到磁盘信息的函数见光盘中)在这个函数里面调用了两次GetLogicalDriveStrings(),第一次调用的目的是获得一个能够容纳包含所有磁盘名的字符串的长度,第二次调用就是获得这个字符串。这个函数在我的电脑上输出结果为:Disk Information:C:/ (FIXED) Total Size: 1619348 KB,Free Size: 1152608 KBD:/ (FIXED) Total Size: 4128672 KB,Free Size: 1323064 KBE:/ (FIXED) Total Size: 6269116 KB,Free Size: 1232324 KBF:/ (FIXED) Total Size: 12269648 KB,Free Size: 1318864 KBG:/ (FIXED) Total Size: 12189408 KB,Free Size: 2980312 KBH:/ (FIXED) Total Size: 2562332 KB,Free Size: 1527204 KBI:/ (CDROM)可看到共有C-I7个盘,其中前6个是硬盘分区。得到这些信息以后,就可以考虑把肉鸡的硬盘当成电影服务器的存储空间了,呵呵。8.肉鸡网络信息收集肉鸡有几块网卡?每个网卡设置是多少IP?子网掩码是多少?网关和MAC地址是多少?——这些信息有什么用?代理、渗透入侵、sniffer都要用到!为此我们需要封装两个函数,一个用来找出网卡的MAC地址,另一个检测其他项。我们先来看看第一个函数:(得到MAC地址的函数见光盘中)其中ASTAT是自定义的一个结构:typedef struct _ASTAT_{ADAPTER_STATUS adapt;NAME_BUFFER NameBuff[30];} ASTAT, * PASTAT;其中ADAPTER_STATUS又是一个复杂的结构,但是它有个成员我们感兴趣,那就是UCHAR adapter_address[6];其实一看就知道这就是网卡的MAC地址,被分成6个部分,每部分1个字节,我们所要做的就是把它转换为可读形式即可。NCB也是一个结构,这个结构虽然复杂,但我们常用到的是其中三个成员:UCHAR ncb_command;//命令PUCHAR ncb_buffer;//返回结果缓冲区WORD ncb_length;//缓冲区大小我们通常是这样用的:先初始化NCB结构,给ncb_command一个命令,给ncb_buffer和ncb_length赋值。然后调用Netbios()函数执行,执行后我们想得到的结果就存放在ncb_buffer中了。Netbios()函数原型为:UCHAR Netbios(PNCB pncb);参数pncb是指向NCB结构的指针。GetMacAddress()有个参数DWORD dwIndex,表示网卡序号,它的值从我下一个函数传过来。该函数的实现过程就是先执行NCBENUM命令,枚举每一块网卡;然后执行NCBRESET命令重置;最后执行NCBASTAT查询网卡状态。这样我们就得到了每块网卡的MAC地址。这个函数涉及到NETBIOS编程,有兴趣的朋友可以参考《Virsual C++网络高级编程》和《Windows网络编程技术》。下面实现第二个函数:(得到网卡信息的函数见光盘中)上面的函数中调用了两个宏ALLOCATE_FROM_PROCESS_HEAP()和DEALLOCATE_FROM_PROCESS_HEAP(),这两个宏的定义分别为:#define ALLOCATE_FROM_PROCESS_HEAP( bytes ) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bytes )#define DEALLOCATE_FROM_PROCESS_HEAP( ptr ) if( ptr ) HeapFree( GetProcessHeap(), 0, ptr )GetAdaptersInfo()函数原型为:DWORD GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo,PULONG pOutBufLen);参数pAdapterInfo是指向IP_ADAPTER_INFO结构的指针。pOutBufLen表示指向IP_ADAPTER_INFO结构的缓冲区大小。IP_ADAPTER_INFO结构成员很多,具体形式可以去查查MSDN。获得MAC地址的时候调用了GetMACAddress()函数。这两个函数在电脑上输出结果为:Network Adapter:Description: 9N1207F-TX/WOL3 PCI Fast Ethernet Adapter - 数据包计划程序微型端口MAC Address: 00:30:f1:49:ab:53IP Address: 192.168.0.6SubNet Mask: 255.255.255.0Default Gateway: 192.168.0.1Description: VMware Virtual Ethernet Adapter for VMnet1MAC Address: 00:50:56:c0:00:01IP Address: 192.168.81.1SubNet Mask: 255.255.255.0Default Gateway:Description: VMware Virtual Ethernet Adapter for VMnet8MAC Address: 00:50:56:c0:00:08IP Address: 192.168.5.1SubNet Mask: 255.255.255.0Default Gateway:第一个是我的网卡,后两个是VMware虚拟出来的。好了,通过上面的一步一步编程,现在你已经可以量身定做适合自己使用偏好的信息检测工具了,同时由于体积非常小,很方便传输,如果肉鸡上有编译器,我们还可以非常快速的自己写一个程序出来,羊毛出在羊身上嘛!祝各位“黑”兄“黑”得愉快!