安全审计机制的设计与实现3277李鑫.docx
《安全审计机制的设计与实现3277李鑫.docx》由会员分享,可在线阅读,更多相关《安全审计机制的设计与实现3277李鑫.docx(19页珍藏版)》请在冰豆网上搜索。
![安全审计机制的设计与实现3277李鑫.docx](https://file1.bdocx.com/fileroot1/2022-12/30/ef1186e8-d4d9-41d2-950a-09e9702a9767/ef1186e8-d4d9-41d2-950a-09e9702a97671.gif)
安全审计机制的设计与实现3277李鑫
上海电力学院
计算机系统安全
课程设计报告
题目:
安全审计机制的设计与实现
学生姓名:
李鑫
学号:
20103277班级:
2010251
院系:
计算机科学与技术学院
专业年级:
信息安全2010级
2013年7月5日
一、实验目的
安全审计机制的设计与实现
要求:
设计并实现安全审计机制,需要具备以下功能:
(1)定义系统中需要监视的审计事件;
(2)监视审计事件,生成统一的日志信息;
(3)日志信息保存到一个指定的日志文件中。
二、实验原理
安全审计中,syslogd进程监视系统内的各种信息,并且根据配置文件的信息,将监视到的内容保存到指定文件中。
可以在windows系统中模拟实现该功能,方法是:
模拟一个syslogd进程,监视指定的一些系统进程信息,并将监视到的内容以格式化的方式保存在文本文件中。
监视方法可以每隔指定的时间将全部进程信息列举一次,并加以保存。
三、实验过程
1、需求分析
根据题目要求,可以抽象出一些概念,要实现系统安全审计机制,则要实现三个功能,第一,定义要监视的事件,例如进程的创建事件,运行事件,及其相关内容。
第二,生成统一的日志信息,也即有大量的格式基本相同的事件。
第三,将产生的事件日志保存在指定的日志文件中。
根据对题目的分析,可以获知需要知道的基本知识有获取进程相关信息的知识、格式化输出的函数、文件操作函数等。
系统环境:
Windows系统
开发工具:
VisualC++6.0
所用语言:
WindowsAPI等
2、安全机制设计,实施
设计:
主程序流程模块
开始
启动监视线程
1、监视指定的进程(每2秒监视一次)
2、获取全部进程信息(每10秒列举一次)
3、监视当前会话窗口(每1秒监视一次)
退出
保存监视文件
保存监视文件
保存监视文件
主进程
启动监视线程
启动监视线程
实施:
定义结构体
structProcessInfo
{
DWORDm_th32ProcessID;
DWORDm_cntThreads;
DWORDm_th32ParentProcessID;
LONGm_pcPriClassBase;
DWORDm_dwPriorityClass;
SYSTEMTIMEm_CreationTime;
SYSTEMTIMEm_ExitTime;
TCHARm_szExeFile[MAX_PATH];
}mProcessInfo[500],pProcessInfo[200];
用于保存进程的有关信息。
定义监视函数BOOLGetProcess(char*ch),监视指定的进程是否在运行,ch为传入的进程名如:
QQ.exe、explorer.exe等。
要知道指定的进程是否在运行,可以根据进程名来判断,将当前进程名与系统中与运行的进程名一一对比,找到则认为有,否则没有。
所以必须列举当前所有进程,故要获取进程快照,并且将进程罗列一遍。
hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
用于创建当前进程快照,
BOOLbProcess=Process32First(hProcessSnap,&pe32);
开始罗列第一个进程,
bProcess=Process32Next(hProcessSnap,&pe32);
罗列下一个进程,
strncmp(pe32.szExeFile,ch,sizeof(pe32.szExeFile))==0
可对比两个字符串是否相同,
若要获取进程优先级,则必须打开进程,可使用
hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pe32.th32ProcessID);
dwPriorityClass=GetPriorityClass(hProcess);
可获取进程优先级,
bRet=GetProcessTimes(hProcess,&CreationTime,&ExitTime,&KernelTime,&UserTime);
可获取进程创建时间,退出时间,内核时间,用户时间,
FileTimeToSystemTime(&CreationTime,&sCreationTime);
可将文件时间转换为系统时间,系统时间与本地时间相差8小时,还得转换
TIME_ZONE_INFORMATIONtz;
GetTimeZoneInformation(&tz);
SystemTimeToTzSpecificLocalTime(&tz,&sCreationTime,&localSTCreationTime);
可实现将系统时间转换为本机本地,即我们平时使用的时间。
定义枚举函数VOIDWINAPIEnumProcess2(char*ch),枚举系统中当前存在的进程,ch为文件保存路径,如:
D:
\\syslog_all.txt。
若要枚举函数,也要创建进程快照,并且一一列举所有进程,仍然使用以下函数
hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
Process32First(hProcessSnap,&pe32)
Process32Next(hProcessSnap,&pe32)
定义监视当前会话窗口的函数VOIDGetTopWindowInfo(char*ch),监视当前活动在最顶层的窗口的类名(classname)和窗口描述(TextString),ch为文件保存路径,如:
D:
\\syslog_all.txt。
监视系统的活动窗口,可以先获取活动窗口的句柄,
hwnd=GetForegroundWindow();
可用于获取活动窗口的句柄,无参数,返回顶层窗口句柄,
GetClassName(hwnd,ClassName,1024);
GetWindowText(hwnd,TextString,1024);
可用于获取窗口类名和窗口文本描述,这些信息保存在字符串ClassName、TextString中,对我们列举信息有用。
定义日志保存函数voidSaveLog(char*ch,ProcessInfomProcessInfo[],inti),将结构体中的信息以固定格式保存到指定的日志文件中,ch为文件保存的完整路径,mProcessInfo[]为事先定义的结构体,用于保存进程的相关信息,i为当前结构体的下标索引。
FILE*file;
file=fopen(ch,"a");
可以定义并打开文件,ch为为文件完整路径,a为打开方式,没有则创建,有则追加到文件尾部。
Fprintf,用于格式化字符到文件中。
fclose(file);,用于在文件使用完毕之后关闭文件。
定义VOIDThreadfunc(void*func,char*ch),用于创建线程,func为线程函数指针,ch为线程函数参数,也就是进程名或是文件保存路径。
HANDLEhThread;
DWORDdwThreadId;
hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)func,ch,0,&dwThreadId);
用于创建线程,func为线程函数,ch为线程函数的参数,函数调用后返回线程句柄。
CloseHandle(hThread);
用于创建完成后关闭线程句柄。
定义VOIDMenu()函数,用于打印一些用户信息。
四、实验演示
五、实验总结
通过本次的课程设计,才真正对编程有了更深的了解。
像系统api的调用,平时有看,但是只是知道,不懂如何用,到真的使用的时候,发现根本不会使用,而且有时候要实现一个功能,却又会找不到使用哪个函数。
系统api的调用最大的困难就是不了解要实现指定的功能要使用的是哪个函数。
这必须得平时学习积累,在设计过程中首先想到的就是列举所有的进程。
由于以前就见过该功能的实现,所以在网上可以找到相关api的介绍,并且编程实现该功能。
这些列举进程的函数的实现方式基本都是固定的,微软已经有了相关的示例介绍这些列举方法。
其次,又想到了将指定进程列举出来监视,这时还是使用将全部进程列举出来和指定进程加以对比,看是否相等来实现。
由于列举进程要列举相关的进程信息,所以定义了一个结构体来存放进程相关信息。
由于涉及到了将信息保存到文件中,所以每当有一个结构体被填充,就将该成员保存到记事本中。
最后,以每秒监视一次的方式,列举了活动的顶层窗口,并且取得了窗口类名和窗口描述。
获得的相关信息保存到了指定的文件中。
本来想的是实现监视系统内的所有进程,每当有一个新的进程启动时就记录它,并表明启动,每当有进程退出时也记录它,并表明退出。
但是在反复思考过后发现一个进程的启动时间是随机的,如果用一般的进程去监视系统内何时有进程启动是不行的。
首先,必须保存当前已经启动的所有进程信息,如果保存到数组中,那么隔一定时间将系统所有进程列举一次,并将列举到的所有进程与数组中的对比。
如果当前系统进程不与数组中的所有进程相同,则认为它是新的进程,可将它添加到数组中。
但是问题又出现了,如果当前系统进程退出了,数组中的内容无法得到及时更新,无法监视到进程的退出,所以必须将数组的每一个进程与系统所有进程加以对比,如果一个进程与系统所有进程都不同,则认为该进程已经退出,清除该结构体中的数据。
经过一般思路分析,要想监视进程启动退出,必须指定一定时间监视所有进程一次,其次,必须将系统进程与保存的所有进程对比,以确定是否有新进程启动;必须将保存的进程与系统所有进程对比,以确定是否有进程退出,也就是要进行两次有方向的对比,一次是系统进程到保存进程的对比,另一次是保存进程与系统进程的对比,情况比较复杂。
而且,这是不考虑系统中有相同进程名的进程,事实上,系统中可以有多个QQ.exe进程或是其他进程,这样情况就更加复杂了。
由于时间有限,所以很多功能和问题都是想到了,感觉很棘手,不好解决。
六、实验缺点及问题
缺点:
本程序比较死板,如果监视指定的进程,则只能每隔指定的时间将进程的相关信息列举一次,保存到文件中,这样会产生大量文件信息。
其次,不能监视到进程的相关线程的更多信息,也不能监视进程的退出时间,只有进程启动了才能将相关信息写入文件中,进程退出后,也不能监视到它的详细退出时间。
也无法监视到进程干了些什么事情,比如iexplore.exe(浏览器进程)访问了那些网站,完全监视不到,只能记录进程的有关规定信息。
本来是守护进程,也就是不可能被结束的进程,本来想做成像360进程那样,在任务管理器里无法结束的形式,但是经过考虑后发现挑战性太大了,该功能无法在短时间内实现。
如要实现该功能,会涉及到进程Hook技术,需要编写.dll文件,这种技术比较高深,而且也没怎么接触过。
其次,该功能会涉及到系统内部调用,有可能涉及到了内核相关知识,所以只是想到了而没有实现。
还有一种做成守护进程的方式,就是将它做成服务的形式,使它在系统后台运行,实现开机启动,但是服务也不是就结束不了,只要停止它,它就不起作用了。
本程序启动了三条线程,而且最多也只有三条线程,无法实现更多线程的启动。
一个功能一个线程,三个功能可以有三个线程。
本程序存在的问题:
本程序经过了多次修改和测试,最终实现了相关的功能,算是一个有些功能的小程序了,但是与真正的进程监视程序相比还是差得很远。
当然程序也是有一些无法解决的错误的,基本上如果按照程序指定的要求输入是不会产生错误的,如果胡乱输入,就会错误。
其次,程序运行时间久了,例如10分钟,则偶尔可能会出现异常终止的现象。
如果点击调试,会显示
七、程序源码
#include
#include
#include
#include
#include
#include
intn=0,q=0;
structProcessInfo
{
DWORDm_th32ProcessID;
DWORDm_cntThreads;
DWORDm_th32ParentProcessID;
LONGm_pcPriClassBase;
DWORDm_dwPriorityClass;
SYSTEMTIMEm_CreationTime;
SYSTEMTIMEm_ExitTime;
TCHARm_szExeFile[MAX_PATH];
}mProcessInfo[500],pProcessInfo[200];
voidSaveLog(char*ch,ProcessInfomProcessInfo[],inti);
//init
VOIDWINAPIEnumProcess2(char*ch)
{
HANDLEhProcessSnap;
HANDLEhProcess;
PROCESSENTRY32pe32;
DWORDdwPriorityClass;
BOOLbRet;
FILETIMECreationTime,ExitTime,KernelTime,UserTime;
SYSTEMTIMEsCreationTime,sExitTime,sKernelTime,sUserTime;
SYSTEMTIMElocalSTCreationTime,localSTExitTime,localSTKernelTime,localSTUserTime;
memset(&sCreationTime,0x0,sizeof(sCreationTime));
memset(&sExitTime,0x0,sizeof(sExitTime));
memset(&sKernelTime,0x0,sizeof(sKernelTime));
memset(&sUserTime,0x0,sizeof(sUserTime));
memset(&localSTCreationTime,0x0,sizeof(localSTCreationTime));
memset(&localSTExitTime,0x0,sizeof(localSTExitTime));
memset(&localSTKernelTime,0x0,sizeof(localSTKernelTime));
memset(&localSTUserTime,0x0,sizeof(localSTUserTime));
L2:
hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if(hProcessSnap==INVALID_HANDLE_VALUE)
{
printf("CreateToolhelp32Snapshot(ofprocesses)");
return;
}
//设置输入参数,结构的大小
pe32.dwSize=sizeof(PROCESSENTRY32);
//开始列举进程
if(!
Process32First(hProcessSnap,&pe32))
{
printf("Process32FirstError");
CloseHandle(hProcessSnap);
return;
}
do
{
//printf("\nPROCESSNAME:
%s",pe32.szExeFile);
dwPriorityClass=0;
hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pe32.th32ProcessID);
if(hProcess==NULL);
//printf("\tOpenProcessError");
else
{
dwPriorityClass=GetPriorityClass(hProcess);//获取优先级
if(!
dwPriorityClass);
//printf("GetPriorityClass");
bRet=GetProcessTimes(hProcess,&CreationTime,&ExitTime,&KernelTime,&UserTime);
FileTimeToSystemTime(&CreationTime,&sCreationTime);
FileTimeToSystemTime(&ExitTime,&sExitTime);
FileTimeToSystemTime(&KernelTime,&sKernelTime);
FileTimeToSystemTime(&UserTime,&sUserTime);
TIME_ZONE_INFORMATIONtz;
GetTimeZoneInformation(&tz);
SystemTimeToTzSpecificLocalTime(&tz,&sCreationTime,&localSTCreationTime);//UTC时间转换为当地时间
SystemTimeToTzSpecificLocalTime(&tz,&sExitTime,&localSTExitTime);
CloseHandle(hProcess);
}
//打印进程相关信息
//printf("\nprocessID=0x%08X,",pe32.th32ProcessID);
//printf("threadcount=%d,",tThreads);
//printf("parentprocessID=0x%08X,",pe32.th32ParentProcessID);
//printf("PriorityBase=%d,",pe32.pcPriClassBase);
//if(dwPriorityClass)
//printf("PriorityClass=%d,",dwPriorityClass);
//else
//printf("PriorityClass=Error,");
//printf("CreationTime=%d-%d-%d%d:
%d:
%d,",
//localSTCreationTime.wYear,localSTCreationTime.wMonth,localSTCreationTime.wDay,
//localSTCreationTime.wHour,localSTCreationTime.wMinute,localSTCreationTime.wSecond);
//printf("ExitTime=%d-%d-%d%d:
%d:
%d,",
//localSTExitTime.wYear,localSTExitTime.wMonth,localSTExitTime.wDay,
//localSTExitTime.wHour,localSTExitTime.wMinute,localSTExitTime.wSecond);
mProcessInfo[n].m_th32ProcessID=pe32.th32ProcessID;
mProcessInfo[n].m_cntThreads=pe32.th32ProcessID;
mProcessInfo[n].m_th32ParentProcessID=pe32.th32ParentProcessID;
mProcessInfo[n].m_pcPriClassBase=pe32.pcPriClassBase;
mProcessInfo[n].m_dwPriorityClass=dwPriorityClass;
mProcessInfo[n].m_CreationTime=localSTCreationTime;
mProcessInfo[n].m_ExitTime=localSTExitTime;
strcpy(mProcessInfo[n].m_szExeFile,pe32.szExeFile);
SaveLog(ch,mProcessInfo,n);
n++;
if(n>=300)n=0;
}while(Process32Next(hProcessSnap,&pe32));
CloseHandle(hProcessSnap);
Sleep(10000);
gotoL2;
}
//监视指定进程是否启动
BOOLGetProcess(char*ch)
{
HANDLEhProcessSnap=NULL;
TCHARszPriority[32]={0};
TCHARszFileName[MAX_PATH]={0};
PROCESSENTRY32pe32={0};
HANDLEhProcess;
DWORDdwPriorityClass;
BOOLbRet;
FILETIMECreationTime,ExitTime,KernelTime,UserTime;
SYSTEMTIMEsCreationTime,sExitTime,sKernelTime,sUserTime;
SYSTEMTIMElocalSTCreationTime,localSTExitTime,localSTKernelTime,localSTUserTime;
memset(&sCreationTime,0x0,sizeof(sCreationTime));
memset(&sExitTime,0x0,sizeof(sExitTime));
memset(&sKernelTime,0x0,sizeof(sKernelTime));
memset(&sUserTime,0x0,sizeof(sUserTime));
memset(&localSTCreationTime,0x0,sizeof(localSTCreationTime));
memset(&localSTExitTime,0x0,sizeof(localSTExitTime));
memset(&localSTKernelTime,0x0,sizeof(localSTKernelTime));
memset(&localSTUserTime,0x0,sizeof(localSTUserTime));
//Takeasnapshotof