苏州市房屋质量管理处:write的奥秘

来源:百度文库 编辑:九乡新闻网 时间:2024/07/07 14:33:08
write的奥秘
    在Linux下我们在使用设备的时候,都会用到write这个函数,通过这个函数我们可以象使
用文件那样向设备传送数据。可是为什么用户使用write函数就可以把数据写到设备里面
去,这个过程到底是怎么实现的呢?
    这个奥秘就在于设备驱动程序的write实现中,这里我结合一些源代码来解释如何使得一
个简简单单的write函数能够完成向设备里面写数据的复杂过程。
    这里的源代码主要来自两个地方。第一是oreilly出版的《Linux device driver》中的
实例,第二是Linux Kernel 2.2.14核心源代码。我只列出了其中相关部分的内容,如果
读者有兴趣,也可以查阅其它源代码。不过我不是在讲解如何编写设备驱动程序,所以不
会对每一个细节都进行说明,再说有些地方我觉得自己还没有吃透。

由于《Linux device driver》一书中的例子对于我们还是复杂了一些,我将其中的一个
例程简化了一下。这个驱动程序支持这样一个设备:核心空间中的一个长度为10的数组
kbuf[10]。我们可以通过用户程序open它,read它,write它,close它。这个设备的名
字我称为short_t。

现在言归正传。
对于一个设备,它可以在/dev下面存在一个对应的逻辑设备节点,这个节点以文件的形式
存在,但它不是普通意义上的文件,它是设备文件,更确切的说,它是设备节点。这个节
点是通过mknod命令建立的,其中指定了主设备号和次设备号。主设备号表明了某一类设
备,一般对应着确定的驱动程序;次设备号一般是区分是标明不同属性,例如不同的使用
方法,不同的位置,不同的操作。这个设备号是从/proc/devices文件中获得的,所以一
般是先有驱动程序在内核中,才有设备节点在目录中。这个设备号(特指主设备号)的主
要作用,就是声明设备所使用的驱动程序。驱动程序和设备号是一一对应的,当你打开一
个设备文件时,操作系统就已经知道这个设备所对应的驱动程序是哪一个了。这个"知道"
的过程后面就讲。

我们再说说驱动程序的基本结构吧。这里我只介绍动态模块型驱动程序(就是我们使用
insmod加载到核心中并使用rmmod卸载的那种),因为我只熟悉这种结构。
模块化的驱动程序由两个函数是固定的:int init_module(void) ;void
cleanup_module(void)。前者在insmod的时候执行,后者在rmmod的时候执行。
init_nodule在执行的时候,进行一些驱动程序初始化的工作,其中最主要的工作有三
件:注册设备;申请I/O端口地址范围;申请中断IRQ。这里和我们想知道的事情相关的只
有注册设备。

下面是一个典型的init_module函数:

int init_module(void){
int result = check_region(short_base,1);/* 察看端口地址*/
……
request_region(short_base,1,"short"); /* 申请端口地址*/
……
result = register_chrdev(short_major, "short", &short_fops); /* 注册设备
*/
……
result = request_irq(short_irq, short_interrupt, SA_INTERRUPT, "short",
NULL); /* 申请IRQ */
……
return 0;
}/* init_module*/

上面这个函数我只保留了最重要的部分,其中最重要的函数是
result = register_chrdev(short_major, "short", &short_fops);
这是一个驱动程序的精髓所在!!当你执行indmod命令时,这个函数可以完成三件大事:
第一,申请主设备号(short_major),或者指定,或者动态分配;第二,在内核中注册设
备的名字("short");第三,指定fops方法(&short_fops)。其中所指定的fops方法就是
我们对设备进行操作的方法(例如read,write,seek,dir,open,release等),如何实现
这些方法,是编写设备驱动程序大部分工作量所在。

现在我们就要接触关键部分了--如何实现fops方法。
我们都知道,每一个文件都有一个file的结构,在这个结构中有一个file_operations的
结构体,这个结构体指明了能够对该文件进行的操作。

下面是一个典型的file_operations结构:
struct file_operations {
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned
long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, struct dentry *);
int (*fasync) (int, struct file *, int);
int (*check_media_change) (kdev_t dev);
int (*revalidate) (kdev_t dev);
int (*lock) (struct file *, int, struct file_lock *);
};

我们可以看到它实际上就是许多文件操作的函数指针,其中就有write,其它的我们就不
去管它了。这个write指针在实际的驱动程序中会以程序员所实现的函数名字出现,它指
向程序员实现的设备write操作函数。下面就是一个实际的例子,这个write函数可以向核
心内存的一个数组里输入一个字符串。

int short_write (struct inode *inode, struct file *filp, const char *buf,
int count){
int retval = count;
extern unsigned char kbuf[10];

if(count>10)
count=10;
copy_from_user(kbuf, buf, count);
return retval;
}/* short_write */
设备short_t对应的fops方法是这样声明的:
struct file_operations short_fops = {
NULL, /* short_lseek */
short_read,
short_write,
NULL, /* short_readdir */
NULL, /* short_poll */
NULL, /* short_ioctl */
NULL, /* short_mmap */
short_open,
short_release,
NULL, /* short_fsync */
NULL, /* short_fasync */
/* nothing more, fill with NULLs */
};

其中NULL的项目就是不提供这个功能。所以我们可以看出short_t设备只提供了
read,write,open,release功能。其中write功能我们在上面已经实现了,具体的实现函
数起名为short_write。这些函数就是真正对设备进行操作的函数,这就是驱动程序的一
大好处:不管你实现的时候是多么的复杂,但对用户来看,就是那些常用的文件操作函数。

但是我们可以看到,驱动程序里的write函数有四个参数,函数格式如下:
short_write (struct inode *inode, struct file *filp, const char *buf, int count)
而用户程序中的write函数只有三个参数,函数格式如下:
write(inf fd, char *buf, int count)
那他们两个是怎么联系在一起的呢?这就要靠操作系统核心中的函数sys_write了,下面
是Linux Kernel 2.2.14中sys_write中的源代码:
asmlinkage ssize_t sys_write(unsigned int fd, const char * buf, size_t count)
{
ssize_t ret;
struct file * file;
struct inode * inode;
ssize_t (*write)(struct file *, const char *, size_t, loff_t *); /* 指向
驱动程序中的wirte函数的指针*/

lock_kernel();
ret = -EBADF;
file = fget(fd); /* 通过文件描述符得到文件指针 */
if (!file)
goto bad_file;
if (!(file->f_mode & FMODE_WRITE))
goto out;
inode = file->f_dentry->d_inode; /* 得到inode信息 */
ret = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file, file->f_pos,
count);
if (ret)
goto out;
ret = -EINVAL;
if (!file->f_op || !(write = file->f_op->write)) /* 将函数开始时声明的
write函数指针指向fops方法中对应的write函数 */
goto out;
down(&inode->i_sem);
ret = write(file, buf, count, &file->f_pos); /* 使用驱动程序中的write函数
将数据输入设备,注意看,这里就是四个参数了 */
up(&inode->i_sem);
out:
fput(file);
bad_file:
unlock_kernel();
return ret;
}

我写了一个简单的程序来测试这个驱动程序,该程序源代码节选如下(该省的我都省了):

main(){
int fd,count=0;
unsigned char buf[10];
fd=open("/dev/short_t",O_RDWR);
printf("input string:");
scanf("%s",buf);
count=strlen(buf);
if(count>10)
count=10;
count=write(fd,buf,count);
close(fd);
return 1;
}

现在我们就演示一下用户使用write函数将数据写到设备里面这个过程到底是怎么实现的:
1,insmod驱动程序。驱动程序申请设备名和主设备号,这些可以在/proc/devIEces中获得。
2,从/proc/devices中获得主设备号,并使用mknod命令建立设备节点文件。这是通过主
设备号将设备节点文件和设备驱动程序联系在一起。设备节点文件中的file属性中指明了
驱动程序中fops方法实现的函数指针。
3,用户程序使用open打开设备节点文件,这时操作系统内核知道该驱动程序工作了,就
调用fops方法中的open函数进行相应的工作。open方法一般返回的是文件标示符,实际
上并不是直接对它进行操作的,而是有操作系统的系统调用在背后工作。
4,当用户使用write函数操作设备文件时,操作系统调用sys_write函数,该函数首先通
过文件标示符得到设备节点文件对应的inode指针和flip指针。inode指针中有设备号信
息,能够告诉操作系统应该使用哪一个设备驱动程序,flip指针中有fops信息,可以告诉
操作系统相应的fops方法函数在那里可以找到。
5,然后这时sys_write才会调用驱动程序中的write方法来对设备进行写的操作。
其中1-3都是在用户空间进行的,4-5是在核心空间进行的。用户的write函数和操作系统
的write函数通过系统调用sys_write联系在了一起。
注意:
对于块设备来说,还存在写的模式的问题,这应该是由GNU C库来解决的,这里不予讨
论,因为我没有看过GNU C库的源代码。
另外,这是一个测试版的文章,请各位朋友们多提意见和建议,非常感谢!

Know Your Enemy
Script KiddIE使用的工具和方法论
Honeynet Project
http://project.honeynet.org
http://www.xfocus.org
Last Modified: 21 July, 2000


我的长官经常对我说:在敌人面前好很好的保护自己,你必须先了解敌人先。(孙子兵法:知己知彼,百战百胜)。这句军事用语现在也很好的应用于网络安全领域中了,就象作战一样,你要保护自己的资源,你需要知道谁是你最大的威胁和他们会怎样攻击。在这个系列中的第一篇文章,就是讨论一种很流行很广泛的来自 Scritp Kiddie所使用的工具和方法,如果你或者你的组织有任何资源连接到Internet上,你就有此类的威胁。

Know Your Enemy文章主要是涉及到blackhatck团体使用的工具,策略和动机。而Know Your Enemy:II主要集中于你怎样能探测这些威胁,判断他们所使用的工具和他们在你系统上寻找什么样的漏洞。Know Your Enemy:III集中讨论攻击者获得ROOT后在系统上怎样操作,特别是他们是如何掩盖他们的踪迹和他们下一步主要干什么。Know Your Enemy: Forensics 涉及了你怎样分析一种攻击。Know Your Enemy: Motives 通过捕获black-hat团体之间的通信和联系来分析他们的动机和心理状态。Know Your Enemy: Worms at War 描述了WORM蠕虫是怎样自动攻击WINDOW系统的。


什么叫Script Kiddie

Script kiddie是一些专门找寻一些容易下手资源的人,他们不专门针对某种特定信息或者目标特定公司,他们的目标是尽可能的用最简单的方法获得ROOT,他们通过搜集一些公开的exploit信息并搜索整个Internet来找寻有这种exploit漏洞的资源,这样,不管怎样,总有某些人会被他们操作。

其中一些高级点的家伙会开发他们自己的工具,并留下一些复杂的后门,另外一些根本就不知道他们做什么,就知道怎样在命令行打"go"的人。忽略他们的技术水平不说,Script kiddie就是共享一些公共策略,随机搜索某个特殊漏洞并利用这个特殊漏洞的人。


他们形成的威胁在哪里?

由于Script kiddie是随机选择目标,所以存在的威胁是你的系统迟早会被扫描到,我知道管理员很惊讶他们的系统在设置以后没几天也没有告诉任何人的时候就被扫描到了,其实这一点也不值得惊讶,因为Scritp kiddie一般是扫描一段网络来操作的。

如果扫描只能限制在几个独立的资源,你可能会很安心,因为Internet上千千万万的机器,扫描到你的机器的几率少之又少。但是,事实不是你想象的这样,目前多数工具能很方面的使用大范围扫描并广泛传播,任何人可以使用他们,使用这些工具的人数增长率呈现惊人的速率。Internet是一个无国界的区域,这种威胁就很快转播到世界各个地方,有这么多人使用这些工具,你被探测就不是问题了。

试图以含糊其词来搪塞你的安全问题会害了你:你或许会认为没有人知道你的系统,你就会安全,或者你认为你的系统没有价值,他们为何要探测你,其实这些系统正是scritp kiddies搜寻的目标--没有任何保护的系统,非常容易得手的系统。


具体方法讨论

Scritp kiddie的方法很简单,扫描Internet有特定缺陷的系统,一但查找到,便对它下手,他们用的许多工具会自动操作,不需要很多的交互。你只要打开工具,然后过几天回来看看你的结果就可以了。没有两个工具是相同的就象没有两个漏洞是一样的,但是虽然如此,许多工具的策略是一样的,第一,开发要扫描的 IP段,然后扫描这些IP段中特定的漏洞。

例如:我们假定一个用户有一个工具可以利用Linux系统上的imap漏洞,如imapd_exploit.c,开始,他们开发一IP数据库来扫描,一旦 IP数据库构建好,用户会想判断系统是否运行LINUX系统。目前许多扫描器可以通过发送不正常的信息包到目标系统并查看他们如果响应便可很方便的判断操作系统,如Fyodor的nmap,然后,工具会判断LINUX系统是否运行着imap服务,最后就是利用imapd_exploit.c程序来进入系统了。

你会想所以这些扫描会有很大的动静,很容易引起注意,但是,很多人没有很好的监视他们的系统,并不认识到他们正被扫描,而且,许多script kiddies在查看他们所要利用的系统时也会保持相当的安静,一旦他们利用这个漏洞进入系统,他们就会使用这个系统作为跳板,并不带任何包袱的扫描整个系统,因为如果这种扫描被抓获,责任是系统管理员而不是那些script-kiddie.

所有这些扫描的结果经常被用来归档或者在其他用户中共享,以便在以后的日子里使用,如用户在最初为了某个漏洞扫描出来的LINUX系统开了那些端口的数据库后,过一点时间,一个新的漏洞被发现以后,用户可以不用重新构建或者扫描新的IP段,他可以很方便的来查看以前归档的数据库并来利用这个新发现的漏洞。其他变相的,用户可以交流或者买卖有漏洞系统的数据库。你可以看Know Your Enemy: Motives文章中的例子,这样造成scritp kiddie可以不扫描系统而破坏你的资源。

有些Black-hats会采用木马或者后门来种植在破坏的系统中,后门允许方便的随时的让攻击者来访问你的系统,而木马使入侵者难于被发现,这些技术可以让他们的操作不显示在任何LOG记录,系统进程或者文件结构上,他可以构建一个舒适安全的环境来扫描Internet,跟详细的信息请看:Know Your Enemy: III。

这些攻击没有限制在一天中的任何时间,许多管理员搜索他们的LOG记录来查询当晚发生了什么,并相信这是攻击者的攻击时间,其实script kiddies在任意时间进行攻击,他们一天24小时的进行扫描,你根本不能考虑到你什么时候会被探测到。而且由于Internet的无边界性,时间也就不确定了,攻击者当地在午夜在攻击,而你这里可能是在当地时间下午一点种。以上对系统漏洞的扫描可以用于多种用途,近来,一种新的拒绝服务攻击--分布式拒绝服务攻击DDos,就是攻击者一个人控制了很多台有漏洞的系统,他可以遥控这些控制的系统来共同对目标系统执行拒绝服务攻击。由于多个系统被使用,所以防卫和判断源攻击地也变的非常困难。要控制多个系统,Script kiddie的策略就变的很有用,有漏洞的系统随机被判断并用来作为DDOS的垫板,越多的系统被控制,DDOS攻击的强度就越大。如 stacheldraht,要了解关于更多的分布式拒绝服务攻击和怎样保护自己,请查看Paul Ferguson站上的Denialinfo。


工具

这些工具一般使用起来很见大,许多工具一般只是几个选项来完成单个目标,开始工具用来构建IP数据库,这些工具很随机的扫描Internet,如一个工具有一个单一的选项,A,B和C,你可以选择一个字母来决定要扫描的网络大小,这工具然后就选择A,B,C相应的IP网络进行扫描。另一个工具使用域名如 z0ne,这个工具通过对域名和子域名的区域传输操作来构造IP数据库,用户通过扫描整个.com或者.edu域来获得2百万或者更多的IP数据库,一旦发现这些IP,它们就被会被工具用户判断版本名字,操作系统,所运行的服务,如果发现系统有漏洞,black-hat就会马上进行攻击。要更好的理解这些工具,请看Know Your Enemy: Forensics。

怎样防止这类威胁


下面的一些步骤你可以比较好的保护你的系统,第一,script kiddie一般找寻容易下手的对象,如一些很公开很容易得手的漏洞系统,保证你的系统和网络不受这些漏洞的影响,www.cert.org 和www.ciac.org是了解这些漏洞很好的资料库。同样地,bugtraq (securityfocus.com的一个邮件列表 ) 也是获得这些漏洞信息很好的地方。另一个保护你自己的方法是只运行你需要的服务,如果你不需要某个服务,关掉它,如果你确实要使用某个服务,确保你的服务版本是最新的。要怎样操作,请看这些文章:Armoring Solaris , Armoring Linux 或者Armoring NT.

上面知道,DNS服务器是经常被用来找寻IP数据库的对象之一,你必须在你的名字服务器上限制区域传送的操作,记录任何未认证的区域传输并跟踪他们。我强烈建议升级BIND到最新的版本,你可以在下面的地址找到:www.isc.org/bind.HTML. 最后监视你被探测的系统,你可以跟踪这些探测操作获得更多对你网络有威胁的举动。

总结

Scritp kiddie会对所有系统有威胁,他们没有任何偏爱,任何系统他们都挑,不计较地点和价值。不管怎样,你迟早会被扫描到。通过了解他们的动机和方法,你可以很好的对付这些威胁而更好的保护你的系统。

Know Your Enemy: II
跟踪Blackhat的举动
Honeynet Project
http://project.honeynet.org
http://www.xfocus.org
Last ModifIEd: July 7, 2000

此文章是系列中的第二篇文章,在第一篇Know Your Enemy, 我们讲述了Script kiddie相关的工具和方法,特别是他们是怎样探测漏洞然后攻击的。在第三篇Know YourEnemy III中我们将会描述Script kiddie在获得ROOT的时候将会做的事情,特别是他们是怎样覆盖踪迹和他们下一步做的是什么。当前这文章,将涉及到有关则怎样跟踪他们的行为。我们会讲述到通过你的系统记录来判断你所需的操作,和你被扫描了以后,你需要了解被探测了以后主要被干什么用,他们使用了那些工具;这里的有些例子主要是基于 Linux操作系统,但是很容易移植到其他Unix系统中,记住,没有绝对的方法能跟踪敌人的每一步,但是,这文章会是一个好的开始。

加强系统LOG记录的安全性
这文章没有主要不是针对入侵检测进行讨论,关于IDS,internet上有很多优秀的源程序供你选择,如果你对入侵检测感兴趣,我建议你使用如 Network Flight Recorder 和snort程序来尝试。此文主要集中在智力收集信息上,特别是,怎样通过查看你的系统记录来获取攻击者操作信息,可能你对你能在自己的LOG记录上能发现多少信息感到很惊讶,但是,在我们讲述查看你记录前,我们首先必须讨论下加强你的系统LOG安全性,如果你不能信任你系统记录的完整性那这些记录将会一文不值,多数black-aht在进入系统之后第一件事情就是怎样更改记录文件,网上非常多类型的Rootkit工具可以清楚记录文件中他们的留下的踪迹 (如cloak),或者阻止所有系统的记录(如伪造过的syslogd),因此,要想查看系统记录,你必须保护好你的记录文件。

这意味着你需要使用远程的LOG服务器,先不管你有多少能力保护自己的系统,在一台被入侵的系统中你不能相信你的任何记录,即使你最好的保护被入侵系统的LOG记录,black-hat也可以简单的使用rm -fr /*来完全清理你的硬盘。要保护这些文件,你必须使你所有系统的LOG记录既有本地记录也发向远程LOG服务器中,这里建立你一个只记录LOG的服务器来收集其他服务器上的信息,如果牵涉到钱的问题,你可以简单使用Linux服务器来充当你的LOG服务器,不过这台服务器必须保证非常安全,需要所有服务关闭,只允许控制台访问(如Armoring Linux所描述),还有必须保证UDP 514口没有对外连接,这样可以保护你的LOG服务器不接受从外界来的不好的或者未认证的LOG信息。

由于上述原因,这里建议你重编译syslogd程序,并让syslogd读取不同的配置文件,如/var/tmp/.conf,此方法能让black- hat没有注意到真实的配置文件位置,这项操作你可以简单的在源代码中修改"/etc/syslog.conf"条目,接着我们可以设置我们新的配置文件把信息记录到本地和远程服务器, 如syslog.txt。这里请你维持一标准的配置文件/etc/syslog.conf指向所有本地LOG,虽然这份配置文件没有用,但可以让攻击者相信记录没有发忘远程记录。另一个选择方法就是让你的系统使用更安全的日志记录工具,如使用某些有完整性检查和其他方面安全加强的系统日志记录工具,如 syslog-ng。

把记录都记录到远程服务器中,将想上面提到的,我们可以基本上相信这些LOG的完整性,而且由于所有系统都记录在单一资源中,就比较容易的判断这些LOG的样式。我们可以在一台机器上记录所有系统记录,你所做的是对比下本地系统和远程系统的不一致性。


类型匹配
通过检查你的记录条目,你可以用来判断那些端口被扫描,许多Script kidde扫描整个网络只为一个漏洞,如你的记录显示你多数系统有来自同一远程系统的连接和同一端口,这就很可能以为着是一次漏洞的扫描,多数LINUX 系统中,TCP Wrapper默认安装的,所以你可以在/var/log/secure里找到多数连接,在其他UNIX系统中,我们可以通过启动inetd后增加-t标志就可以记录所有Inetd连接。下面是一个典型的漏洞扫描,是为了扫描wu-ftpd漏洞:

/var/log/secure
Apr 10 13:43:48 mozart in.ftpd[6613]: connect from 192.168.11.200
Apr 10 13:43:51 bach in.ftpd[6613]: connect from 192.168.11.200
Apr 10 13:43:54 hadyen in.ftpd[6613]: connect from 192.168.11.200
Apr 10 13:43:57 vivaldi in.ftpd[6613]: connect from 192.168.11.200
Apr 10 13:43:58 brahms in.ftpd[6613]: connect from 192.168.11.200

上面我们可以看到源主机192.168.11.200在扫描我们的网络,注意为何源主机连续扫描每个IP,这些记录就归功于LOG服务器,你可以方便的判断每个类型,连续的连接端口21,FTP,就暗示着攻击者在寻找wu-ftpd漏洞。一般来说,扫描是倾向于阶段性的,某些人发布了一个 imap漏洞的利用代码,你就会发现记录里有imap扫描突然增多,下一个月如果有FTP利用程序发布,记录就会转向ftp突然增多,你可以在这个地址 http://www.cert.org/advisories/获得当前最新的漏洞建议。有时,一个工具也会在同一时间里扫描多种漏洞,因此你也会看到一个源主机连接多个端口。

记住,如果你没有记录这些服务,你就不会知道你被扫描,例如,多数RPC连接没有被记录,但是服务记录是一件简单的事情,你可以通过在 /etc/inetd.conf增加条目来让TCP WRAPPER进行记录,如你在/etc/inetd.conf里增加NetBus条目,你就可以通过定义TCP Wrapper来安全的拒绝和记录NETBUS的连接(更多信息请查看ids).


判断使用工具



有些时候你可以判断什么样的工具在扫描你的系统,因为一般工具都是扫描特殊的漏洞,如ftp-scan.c,如果你发现只是一个端口被扫描,一般他们使用的是单任务工具,但是也存在很多工具扫描多种系统漏洞和薄弱处,举两个非常有用的工具如jsbach写的sscan和Fyodor写的nmap,我只所以选择了这两个工具是因为他们能代表两种类别的扫描工具,这里强烈建议你用这些工具扫描下你自己的网络,或许你会得到让你吃惊的结果。

注:sscan工具是一个比较老的工具了,在这里只是把sscan拿来讨论,要扫描你网络系统的漏洞,这里建议使用Nessus。

sscan代表着以"所有目标"为目的的Script kiddie扫描工具,它扫描网络一套的网络漏洞,它可以让你定制规则来对新漏洞的增加,你只要传递工具一个网络和网络掩码,其他的事情它来做,不过这个工具需要有ROOT权利才能使用,它的输出很容易理解,它会提供一个简洁的对漏洞服务的描述,所有你要做的就是让sscan扫描网络,然后你提取 "VULN"的值,然后运行"exploit du jour",下面是sscan对系统mozart (172.17.6.30)的扫描:



otto #./sscan -o 172.17.6.30

--------------------------<[ * report for host mozart *
<[ tcp port: 80 (http) ]> <[ tcp port: 23 (telnet) ]>
<[ tcp port: 143 (imap) ]> <[ tcp port: 110 (pop-3) ]>
<[ tcp port: 111 (sunrpc) ]> <[ tcp port: 79 (finger) ]>
<[ tcp port: 53 (domain) ]> <[ tcp port: 25 (smtp) ]>
<[ tcp port: 21 (ftp) ]>

--<[ *OS*: mozart: os detected: redhat linux 5.1
mozart: VULN: linux box vulnerable to named overflow.
<[ *CGI*: 172.17.6.30: tried to redirect a /cgi-bin/phf request.
<[ *FINGER*: mozart: root: account exists.
<[ *VULN*: mozart: sendmail will 'expn' accounts for us
<[ *VULN*: mozart: linux bind/iquery remote buffer overflow
<[ *VULN*: mozart: linux mountd remote buffer overflow
---------------------------<[ * scan of mozart completed *

Nmap代表"原始数据"工具集,它不告诉你系统有什么漏洞存在,相反,它告诉你系统有什么端口打开,你必须自己判断安全问题,Nmap很快变成扫描端口的首选,它是能很好的端口扫描工具并集合多种功能的工具包括OS探测,有多种端口组合选择,包括UDP和TCP扫描,不过这个工具需要你有一定的网络技能来使用这个工具并解析这些数据,下面是nmap对同一系统扫描的结果:
otto #nmap -sS -O 172.17.6.30

Starting nmap V. 2.08 by Fyodor (fyodor@dhp.com, www.insecure.org/nmap/)
Interesting ports on mozart (172.17.6.30):
Port State Protocol Service
21 open tcp ftp
23 open tcp telnet
25 open tcp smtp
37 open tcp time
53 open tcp domain
70 open tcp gopher
79 open tcp finger
80 open tcp http
109 open tcp pop-2
110 open tcp pop-3
111 open tcp sunrpc
143 open tcp imap2
513 open tcp login
514 open tcp shell
635 open tcp unknown
2049 open tcp nfs

TCP Sequence Prediction: Class=truly random Difficulty=9999999 (Good luck!)
Remote operating system guess: Linux 2.0.35-36

Nmap run completed -- 1 IP address (1 host up) scanned in 2 seconds

通过检查你的LOG记录,你可以判断那个工具在扫描你,不过你需要理解这些工具是如何工作的你才能判断出扫描你的工具,第一,sscan会在记录中留下下面的记录(这个是默认扫描没有增加任何修改和其他配置文件):
/var/log/secure
Apr 14 19:18:56 mozart in.telnetd[11634]: connect from 192.168.11.200
Apr 14 19:18:56 mozart imapd[11635]: connect from 192.168.11.200
Apr 14 19:18:56 mozart in.fingerd[11637]: connect from 192.168.11.200
Apr 14 19:18:56 mozart ipop3d[11638]: connect from 192.168.11.200
Apr 14 19:18:56 mozart in.telnetd[11639]: connect from 192.168.11.200
Apr 14 19:18:56 mozart in.ftpd[11640]: connect from 192.168.11.200
Apr 14 19:19:03 mozart ipop3d[11642]: connect from 192.168.11.200
Apr 14 19:19:03 mozart imapd[11643]: connect from 192.168.11.200
Apr 14 19:19:04 mozart in.fingerd[11646]: connect from 192.168.11.200
Apr 14 19:19:05 mozart in.fingerd[11648]: connect from 192.168.11.200


/var/log/maillog
Apr 14 21:01:58 mozart imapd[11667]: command stream end of file, while reading line user=??? host=[192.168.11.200]
Apr 14 21:01:58 mozart ipop3d[11668]: No such file or Directory while reading line user=??? host=[192.168.11.200]
Apr 14 21:02:05 mozart sendmail[11675]: NOQUEUE: [192.168.11.200]: expn root


/var/log/messages
Apr 14 21:03:09 mozart telnetd[11682]: ttloop: peer died: Invalid or incomplete multibyte or wide character
Apr 14 21:03:12 mozart ftpd[11688]: FTP session closed

sscan也扫描cgi-bin漏洞,这些探测没有通过syslogd记录,你可以在access_log中发现:

/var/log/httpd/access_log
192.168.11.200 - - [14/Apr/1999:16:44:49 -0500] "GET /cgi-bin/phf HTTP/1.0" 302 192
192.168.11.200 - - [14/Apr/1999:16:44:49 -0500] "GET /cgi-bin/Count.cgi HTTP/1.0" 404 170
192.168.11.200 - - [14/Apr/1999:16:44:49 -0500] "GET /cgi-bin/test-cgi HTTP/1.0" 404 169
192.168.11.200 - - [14/Apr/1999:16:44:49 -0500] "GET /cgi-bin/php.cgi HTTP/1.0" 404 168
192.168.11.200 - - [14/Apr/1999:16:44:49 -0500] "GET /cgi-bin/handler HTTP/1.0" 404 168
192.168.11.200 - - [14/Apr/1999:16:44:49 -0500] "GET /cgi-bin/webgais HTTP/1.0" 404 168
192.168.11.200 - - [14/Apr/1999:16:44:49 -0500] "GET /cgi-bin/websendmail HTTP/1.0" 404 172
192.168.11.200 - - [14/Apr/1999:16:44:49 -0500] "GET /cgi-bin/webdist.cgi HTTP/1.0" 404 172
192.168.11.200 - - [14/Apr/1999:16:44:49 -0500] "GET /cgi-bin/faxsurvey HTTP/1.0" 404 170
192.168.11.200 - - [14/Apr/1999:16:44:49 -0500] "GET /cgi-bin/HTMLscript HTTP/1.0" 404 171
192.168.11.200 - - [14/Apr/1999:16:44:49 -0500] "GET /cgi-bin/pfdisplay.cgi HTTP/1.0" 404 174
192.168.11.200 - - [14/Apr/1999:16:44:49 -0500] "GET /cgi-bin/perl.exe HTTP/1.0" 404 169
192.168.11.200 - - [14/Apr/1999:16:44:49 -0500] "GET /cgi-bin/wwwboard.pl HTTP/1.0" 404 172
192.168.11.200 - - [14/Apr/1999:16:44:50 -0500] "GET /cgi-bin/ews/ews/architext_query.pl HTTP/1.0" 404 187
192.168.11.200 - - [14/Apr/1999:16:44:50 -0500] "GET /cgi-bin/jj HTTP/1.0" 404 163

注意上面对所有端口(SYN, SYN-ACK, ACK)进行了完整的连接,这是因为sscan判断应用层上的内容,不仅仅是sscan想知道你的ftp端口是否打开而且要知道什么样的FTP程序在运行,其他的imap,pop也是这样,你可以通过sniffit来嗅探起踪迹,sniffit是常用来嗅探密码的工具:
mozart $ cat 172.17.6.30.21-192.168.11.200.7238
220 mozart.example.net FTP server (Version wu-2.4.2-aCADem[BETA-17](1) Tue Jun 9 10:43:14 EDT 1998) ready.

就想你上面所见到的,通过一次完整的连接来判断什么样版本的wu-ftpd在运行,当你在LOG文件里看到一次完整的连接,你就应该想到很可能是一次查找漏洞的工具在扫描。

Nmap,类似许多扫描器,并不关心你运行了什么,而是你运行了什么样特殊的服务,Nmap有一套功能强大的选项,让你选择什么类型的连接,包括SYN, FIN, Xmas, Null等,你可以在nmap_doc.html文章中获得详细的描述。由于使用到这些选项,你的记录上会因远程用户选择不同而不同,如果使用-sT标志,暗示一次完整的连接,你在记录上会看到和sscan类似的记录,不过nmap默认情况下扫描更多的端口:


/var/log/secure
Apr 14 21:25:08 mozart in.rshd[11717]: warning: can't get client address: Connection reset by peer
Apr 14 21:25:08 mozart in.rshd[11717]: connect from unknown
Apr 14 21:25:09 mozart in.timed[11718]: warning: can't get client address: Connection reset by peer
Apr 14 21:25:09 mozart in.timed[11718]: connect from unknown
Apr 14 21:25:09 mozart imapd[11719]: warning: can't get client address: Connection reset by peer
Apr 14 21:25:09 mozart imapd[11719]: connect from unknown
Apr 14 21:25:09 mozart ipop3d[11720]: warning: can't get client address: Connection reset by peer
Apr 14 21:25:09 mozart ipop3d[11720]: connect from unknown
Apr 14 21:25:09 mozart in.rlogind[11722]: warning: can't get client address: Connection reset by peer
Apr 14 21:25:09 mozart in.rlogind[11722]: connect from unknown



你必须注意Nmap有-D选项,它可以让用户来伪造源地址,你或许会在同一时间里看到从15个不同源主机来的扫描,其实这些地址真实的只有一个,所以从这些源地址中判断真实地址是比较困难的事情。还有,用户还会选择-sS标志,这是一隐蔽扫描选项,只发送SYN包,如果远程系统回应,连接就直接通过RST 包来断开,所以这时候的记录会如下:

/var/log/secure
Apr 14 21:25:08 mozart in.rshd[11717]: warning: can't get client address: Connection reset by peer
Apr 14 21:25:08 mozart in.rshd[11717]: connect from unknown
Apr 14 21:25:09 mozart in.timed[11718]: warning: can't get client address: Connection reset by peer
Apr 14 21:25:09 mozart in.timed[11718]: connect from unknown
Apr 14 21:25:09 mozart imapd[11719]: warning: can't get client address: Connection reset by peer
Apr 14 21:25:09 mozart imapd[11719]: connect from unknown
Apr 14 21:25:09 mozart ipop3d[11720]: warning: can't get client address: Connection reset by peer
Apr 14 21:25:09 mozart ipop3d[11720]: connect from unknown
Apr 14 21:25:09 mozart in.rlogind[11722]: warning: can't get client address: Connection reset by peer
Apr 14 21:25:09 mozart in.rlogind[11722]: connect from unknown



注意在连接中显示所有连接错误的,原因是SYN-ACK正确的顺序在完成完整连接之前被破坏,守护程序就判断不出源地址,这样记录虽然能记录被扫描,但不能记录谁在扫描,更甚的是,有些系统(包括新内核的LINUX),没有一个错误记录会被记录。应用Fyodor的话"...基于所有 'connection reset by peer'信息,linux2.0.XX有点古怪--事实上每个其他系统(包括2.2和2.1后内核)会什么都不显示,这个BUG(accept()在完成3次连接之后返回)已经修补"

Nmap包含其他的一些隐蔽扫描选项,如:-sF, -sX, -sN ,在记录中会如下显示:

/var/log/secure

就是说没有任何显示,就是说你被扫描会你永远不会知道。所有这三种类型都是同样的结果,你只能记录-sT标志的扫描。要探测这些隐蔽扫描,你需要使用不同的记录程序如tcplogd或者ippl,某些商业防火墙也能探测到这些扫描,如Checkpoint Firewall 1.

判断他们是否进入

一旦你知道你被扫描了,下一个大问题就是"他们有没有进入你的系统",现在多数远程利用程序基于缓冲溢出,简单的陈述就是当程序(一般是守护程序)接受到超多的输入后,会覆盖正确的内存区域,导致代码被执行,而获得远程ROOT访问,关于缓冲溢出更多信息,你可以查看Aleph1的phrack49- 14.txt文章。

你一般可以在/var/log/messages或者/var/adm/messages文件中判断缓冲溢出攻击,如mountd。下面是对imapd进行的攻击,你在maillog里会发现如下的缓冲溢出信息:

Apr 14 04:20:51 mozart mountd[6688]: Unauthorized access by NFS client 192.168.11.200.
Apr 14 04:20:51 mozart syslogd: Cannot glue message parts together
Apr 14 04:20:51 mozart mountd[6688]: Blocked attempt of 192.168.11.200 to mount
~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~
~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~P~
P~P~P3Û3À°^[Í~@3Ò3À~KÚ°^FÍ~@þÂuô1À°^BÍ~@~EÀubëb^V¬<ýt^FþÀt^Këõ°0þÈ~HFÿëì^°^B~
I^FþÈ~IF^D°^F~IF^H°f1ÛþÃ~IñÍ~@~I^F°^Bf~IF^L°*f~IF^N~MF^L~IF^D1À~IF^P°^P~IF^H°
fþÃÍ~@°^A~IF^D°f³^DÍ~@ë^DëLëR1À~IF^D~IF^H°fþÃÍ~@~Hð?1ÉÍ~@°?þÁÍ~@°?þÁÍ~@¸.bin@~
I^F¸.sh!@~IF^D1À~HF^G~Iv^H~IF^L°^K~Ió~MN^H~MV^LÍ~@1À°^A1ÛÍ~@èEÿÿÿÿýÿPrivet
ADMcrew~P(-^E^H(-^E^H(-^E^H(-^E^H(-^E^H(-^E^H(-^E^H(-^E^H(-^E^H(Apr 14 04:20:51
mozart ^H(-^E^H(-^E^H(-^E^H(-^E^H(-^E^H(-^E^H(-^E^H(-^E^H(-^E^H(-^E^H(-^E^H(-^
E^H(-


当你在LOG文件里看到如上的信息时,就可以判断有人尝试利用漏洞进入你的系统,不过是否成功就比较难判断,一种方法是,在漏洞利用之后查看是否有任何远程主机进入你系统,如果有从远程系统中成功的LOGIN,他们就已经进入你的系统,另一个线索是在/etc/passwd文件中查找可疑的帐户如 "moof", "rewt", "crak0", 或 "w0rm" 是否UID为0,一旦攻击者获得访问权利,他们会清除他们的记录和改装你的LOG记录,关于这方面更多信息,请查看Know Your Enemy: III. 如果真的类似上面这样的操作,你就很难在你破坏的系统上获得任何信息。下一步该怎么做就是另一个话题了,这里建议你查看下面的文件:http: //www.cert.org/nav/recovering.html

为了帮助我查找LOG文件中的反常记录,我写了一脚本程序来检查,关于更详细的查找和排序LOG文件,你可以查看此文:Marcus Ranum.(http://www.nfr.net/firewall-wizards/mail- archive/1997/Sep/0098.html)

这里是这个脚本的程序:

Korn shell script
总结

你系统记录文件会告诉你详细的关于攻击者的信息,但是,首先你必须保证你LOG文件的完整性。一个最好的方法就是使用远程LOG服务器来接受和存储所有系统的系统。这样你可以判断LOG文件的信息类型,基于这些类型和LOG条目,你可以判断black-hat到底在干什么和判断他们使用的工具。根据这些知识,你可以更好的保护你的系统。