大陆银行在香港搜寻收购目标
中国大陆的游客已经爱上了在香港的购物体验。手头阔绰的大陆银行是否也渴望体验一下呢?
香港资产第八大银行永隆银行有限公司(Wing Lung Bank Ltd., 简称:永隆银行)出售股权或许是对此的第一个检验。永隆银行的控股股东伍氏家族拟出售所持永隆银行53.12%的股权。据知情人士透露,中国工商银行股份有限公司(Industrial & Commercial Bank Of China Ltd., 简称:工商银行)和澳新银行(Australia & New Zealand Banking Group Ltd.) 双双入局。银行家预计对伍氏家族所持股权的报价可能会达到50亿美元。两家银行将于周三提交最终收购提议。
目前工商银行似乎占有一定优势。这家中国资产最大的银行从2006年10月的首次公开募股(IPO)中筹资220亿美元,而且,与西方的竞争对手相比,它所受的美国次债危机的打击相对较小。澳新银行按市值计是澳大利亚第四大银行,也是在国际上表现最积极的一个。不过,该行周三公布,由于为全球信贷危机波及的贷款计提拨备,上半财年利润出现下降,这也是该行10年来首次出现利润下降。这一消息令该行遭受了不小的打击。
眼下,可能达成更多交易的前景使香港其他家族控股银行获得了不少关注。与永隆银行处于类似处境的其他潜在被收购对象包括东亚银行有限公司(Bank of East Asia Ltd., 简称:东亚银行)、创兴银行有限公司(Chong Hing Bank Ltd., 简称:创兴银行)、大新金融集团有限公司(Dah Sing Financial Holdings Ltd., 简称:大新金融)以及永亨银行有限公司(Wing Hang Bank Ltd., 简称:永亨银行)。
摩根士丹利(Morgan Stanley)的分析师在最近的一份报告中写道,如果永隆银行被收购,他们预计整个行业会发生进一步的整合,报告还指出,永亨银行、大新金融以及创兴银行都拥有类似的家族控股所有权结构。这些分析师表示,从基本面来看,这些银行的股票价格在2008年将会受到贷款强劲增长和净利息收益率上升的提振。
这些银行的大股东都在观望永隆银行股权出售的进程,从中了解永隆银行股权估价的情况。如果买家出价慷慨,可能会促使他们出售手中的股权。永隆银行在香港交易的股价周五收于135港元(合17.33美元),今年迄今累计涨幅达41%,因为投资者预计收购方的报价会高于其当前股价,因而进一步推高股价。香港其他类似银行并未出现如此大的涨幅。
ING Investment Management高级投资经理Oscar Leung说,考虑到成本结构以及向客户提供更加复杂产品的需要,小银行很难在香港生存下去。因此他认为行业整合的趋势还将继续下去。
香港的银行业市场目前由汇丰控股有限公司(HSBC Holdings PLC, 简称:汇丰控股)、中国银行(Bank of China Ltd.)等几家大银行所主导,这些银行的全球性平台促使它们有更大的积 性进行技术升级,使用最先进的技术,并且不断为全球公司客户提供更加全面的服务。这些因素使得家族控股银行难以与之竞争。Oscar Leung说,那些想要向潜在收购目标下注的投资者需要耐心些,因为眼下很难预测哪些银行会出售股份以及何时会出售股份。
即使香港的银行有意出售,中国大陆的银行也不会是唯一感兴趣的买家。不过,香港银行和中国大陆银行之间的联系还是有着特别的渊源。自1997年香港回归以来,这个位于珠江三角洲的港口城市已经成为中国企业寻求海外发展的跳板。
对于中国大陆的银行来说,增强香港业务不仅可以提供机会使它们获得更多服务于富有客户的经验,也为他们开展贸易融资业务提供 前沿阵地。
中国四大国有银行中的三家在几年前还被认为资不抵债,但是自2005年10月以来它们通过IPO共筹得了超过400亿美元的资金。此外,他们因持有美国次债相关资产而遭受的打击远远小于其他大型银行。眼下,虽然他们正在尝试进行海外交易,但却避开了不熟悉市场上的收购交易。香港和中国大陆在语言和文化上的密切联系,再加上香港的资本主义经济制度,这些都为大陆银行培训未来到海外就职的经理人提供了理想环境。
律师事务所Slaughter & May合伙人之一Benita Yu说,大陆银行收购香港本土银行是大陆银行业务的合理扩张,随着香港家族控股银行中老一辈纷纷退出江湖,此类收购的数量有望增多。
此前曾有人表示,伍氏家族53.12%的控股权在2007年年底可能会使其获得3至3.6倍于这部分股权帐面价值的资金。据美林(Merrill Lynch)分析师的计算,这部分股权帐面价值的三倍相当于每股161.25港元。伍氏家族控股权的出售可能引发对永隆银行其余流通股的收购。
一些香港银行似乎也在引进合作伙伴,以保持竞争实力,或者抵抗行业整合的侵蚀。去年,中银香港(控股)有限公司以5.06亿美元购入了东亚银行5%的股份。外界普遍认为,这是吓跑潜在收购方的一个举措。
按贷款规模计,东亚银行是香港第四大银行,在香港的市场份额为7.5%。东亚银行董事长李国宝(David Li)最近也迫于压力减少 在这家银行中的职责。此前,他刚刚与美国证券交易委员会(U.S. Securities and Exchange Commission)就一项内部交易调查达成和解,他涉嫌在新闻集团(News Corp.)收购《华尔街日报》所有者道琼斯公司(Dow Jones & Co.)的交易中进行内部交易。东亚银行的市值大约为674亿港元(合87亿美元)。
另一家在香港银行业建立战略立足点的银行是三菱东京UFJ银行(Bank of Tokyo-Mitsubishi UFJ)。今年3月,这家日本银行同意出资约4.72亿港元把对大新金融的持股比例从12%提高至15%。大新金融是大新银行集团有限公司(Dah Sing Banking Group Ltd., 简称:大新银行集团)的母公司。
创兴银行在一份声明中表示,并没有寻求出售。但是,它已经为离开家族式管理后的光景作准备了。比如,创兴银行更改了名称,将公司最大股东刘氏家族的姓氏从公司名称中去掉,以减少与这个家族的联系。
东亚银行、大新金融和永亨银行均拒绝置评,或者无法联系到进行置评。
黑客理论基础
我写这篇文章的目的是为了引导现在所谓国内的越来越多的所谓的“黑客”。现在所谓的新兴的年轻黑客们及其缺乏一种正确的道德理论的引导,希望看过我这篇文章的人能往一些更正确的方向发展吧。写纯理论的东西,文笔不好,请见谅。
介绍
传统上,黑客指那些喜欢去修补软件和电子系统的人。黑客们认为探索和学习操作系统是一种享受。他们热爱发现新的电子工作方式。时到今日, 黑客被赋予了一个新的意思:那些为了个人目的故意去破坏系统的忍。技术上我们可以叫那些人cracker,又或者罪恶的黑客,非法黑客等等。Cracker入侵系统为的时一些不轨的企图, 他们时为了个人的利益而采取行动的,例如获得名声或者金钱甚至时为了报复。他们盗取,更改,或者删除重要的信息, 并且经常令人感到痛苦,而不是快乐。我们所说的黑客中的好人,也就是所谓的白帽子黑客不喜欢去做类似所谓的黑客里的坏人-黑帽子黑客的不道德的行为,也不愿和那些人同流。但是无论如何,黑客这个名称已经给相当的人留下的不好的印象,黑客代表着计算机犯罪,虽然事实上这是完全不正确的。很多不怀好意的黑客都声称自己不从事破坏活动而且还经常帮助别人,靠,真是说的好听,其实他们大部分都是一些电子盗贼。简单的来说吧,坏的黑客就是那些总是想去破坏的人,有道德的黑客就是那些保护系统免受非法入侵的人。
什么是有道德的黑客行为
一个有道德的黑客拥有的不仅仅是技术, 还包括了正确的思想方向, 他们是值得信赖的。有道德进行黑客行为是最为一种保护自己系统的测试手段,而不是破坏。有道德的黑客行为指的是渗透测试或者白帽子行为,尽管所用的方法,工具, 技巧等等都和那些恶意黑客一样,但是本质上的区别产生了根本的不同-有道德的黑客行为是合法的,是经过特定的许可的。有道德的黑客行为是为了从黑客的角度去发现系统的弱点从而使得系统更加的安全。安全检测其实就是这一类的行为, 要用潜在的入侵者的思路去发现特定的系统的漏洞和弱点,这也是专业计算机安全专家必须拥有的特质。
用潜在非法入侵者的思路去合法的入侵(或者叫安全检测)特定的系统,这是有道德入侵的根本。 随着黑客知识的不断更新和漏洞的不断增加, 所有的系统都在承受的被攻击的可能性。为了保护特定的电脑或者网络系统不受到坏人的骚扰, 仅仅防范一些很明显的漏洞已经不足够万事无忧。从更深的层次去理解黑客的手段才是更进一步防范非法入侵的有效办法。
黑客行为都是建立在软弱的系统安全和没有泄漏的可被攻击的弱点上的。 防火墙,加密技术, VPNs都可能让人在心里上产生一种误解,它们都是安全的。这些安全系统常常都集中在防范高危险性系统弱点上。合法的入侵特定的系统可以发现一些不明显的系统漏洞从而让已经拥有了这些防范措施的系统更加安全。这是让你想保护的远离被攻击的最好的办法,否则系统被攻破只是时间上的问题而已。当非法入侵者不断利用各种新的技术武装自己的时候,我们是不是也必须像他们一样从而来保护我们需要保护系统呢?当你作为一个有道德黑客,你必须知道应该找寻些什么和如何利用它们去阻止那些不想见到的结果。
理解系统面临的危险
知道你的系统面临着来自世界各地的黑客的窥视是一件事情,另一件事情则是去明白具体的攻击你所要保护的系统的攻击手法。 不少信息安全漏洞不是因为它们自身不安全,而是若干个漏洞共同作用的结果。比如说一个默认的windows的系统设置,一个SQL的弱口令,一个无线网络服务器也许都是不主要的系统安全弱点,但是把这三个不同的东西结合起来,可能就会产生很严重的问题。中国有句古话叫做堤溃蚁孔, 就是这个意思了。
非物理性攻击
任何系统的操作者都可能被利用来进行系统的入侵,比如终端用户甚至是你自己, 在使用这个系统任何一个人都可能是这个系统或者网络最大的弱点。信任是人的天性, 这就可能造成一种特殊的攻击――社会工程学攻击。简单的说社会工程学是一种攻击行为, 攻击者利用人际关系的互动性所发出的攻击:通常攻击者如果没有办法通过物理入侵的办法直接取得所需要的资料时,就会通过电子邮件或者电话对所需要的资料进行骗取,再利用这些资料获取主机的权限以达到其本身的目的。关于社会工程学的介绍可以参考我的另一篇文章《没有电脑的入侵-深入浅出社会工程学》(http://bbs.s8s8.net/forums/index.php?showtopic=19243)。或者小金美女的《没有硝烟的战争——社会工程学 》(http://bbs.s8s8.net/forums/index.php?showtopic=30455)。据他说他写的比我的生动,我说他的不够专业,哈哈。
其他的常见的对于获取信息有效的手段都是物理上的攻击。黑客进入系统所在的大厦,计算机机房或者一些储存有敏感信息的地方。甚至在特定地点的垃圾堆可能找到有用的东西,比如记录密码的纸张,网路结构图或者其他有用的信息。所以碎纸机的作用是不能忽视的。
by gouy2k (gouy2k@gmail.com)
Rootkit技术发展史
瘟神的尾行
——Rootkit技术发展史
作者:小金
一. 无法驱逐的“助手”
网管小张正在手忙脚乱的寻找他的手工杀毒工具包,因为他在安装一个网管工具的时候无意中走了神,点击了“下一步”按钮后才惊觉安装程序的界面里一个不引人注目的角落里写着“安装CNNIC网络实名”这一行小字,而且最开头部分有一个小小的勾。于是著名的“中国网民的得力助手”便理所当然的在他的机器里安了家。
心里把厂商骂了十八遍的小张终于翻出了他外出修机时最得意的工具IceSword和超级巡警,果然在进程列表和SSDT列表里发现了红色警报,小张笑了笑,对付这些一般用户无法卸载的恶意流氓,自己可谓经验丰富了,当下便三下五除二的把CNNIC的进程给终结了,SSDT也给恢复了初始状态,然后小张去删除注册表启动项——突然发出的一个错误提示声音把小张吓了一跳,再定睛一看,他的笑容凝固了:“删除项时出错”。不会吧?小张急忙去删除CNNIC目录,结果彻底愣在了那里,系统弹出的错误提示很明确的告诉他,“无法删除文件,文件可能正在被使用”。怎么回事?小张一下子没了头绪……
达尔文的进化论告诉我们,“物竞天择,适者生存”,同样,在这安全与入侵的网络世界里,也在进行着这样一场选择的过程……
二. 被AIDS纠缠的互联网
Rootkit是什么?如果您在几年前就是本刊的读者,那您一定已经看过小金写的涉及Rootkit的相关文章,一种在当时可以被称为“艾滋病毒AIDS”的技术产物,只是,在这场“适者生存”的残酷游戏里,最终存活的,只剩下Rootkit了,于是,今天的Rootkit地位已经等同于当年的感冒病毒——因为它实在是太普遍了,在用户上网的同时,瘟神时刻都紧随着其后,以求伺机而入。
小知识:什么是Rootkit?
Rootkit自身也是木马后门或恶意程序的一类,只是,它很特殊,为什么呢?因为,你无法找到它。
正如自然界的规则一样,最流行的病毒,对生物的伤害却是最小的,例如一般的感冒,但是最不流行的病毒,却是最夺命的。Rootkit木马就是信息世界里的AIDS,一旦感染,就难以用一般手段消灭了,因为它和自然界里的同类做的事情一样,破坏了系统自身检测的完整性——抛开术语的描述也许难以理解,但是可以配合AIDS的图片想象一下,由于AIDS破坏了人体免疫系统,导致白细胞对它无能为力,只能眼睁睁看着人体机能被慢慢破坏。计算机系统没有免疫功能,但是它提供了对自身环境的相关检测功能——枚举进程、文件列表、级别权限保护等,大部分杀毒软件和进程工具都依赖于系统自带的检测功能才得以运作,而Rootkit木马要破坏的,正是这些功能。
要了解Rootkit木马的原理,就必须从系统原理说起,我们知道,操作系统是由内核(Kernel)和外壳(Shell)两部分组成的,内核负责一切实际的工作,包括CPU任务调度、内存分配管理、设备管理、文件操作等,外壳是基于内核提供的交互功能而存在的界面,它负责指令传递和解释。由于内核和外壳负责的任务不同,它们的处理环境也不同,因此处理器提供了多个不同的处理环境,把它们称为运行级别(Ring),Ring让程序指令能访问的计算机资源依次逐级递减,目的在于保护计算机遭受意外损害——内核运行于Ring 0级别,拥有最完全最底层的管理功能,而到了外壳部分,它只能拥有Ring 3级别,这个级别能操作的功能极少,几乎所有指令都需要传递给内核来决定能否执行,一旦发现有可能对系统造成破坏的指令传递(例如超越指定范围的内存读写),内核便返回一个“非法越权”标志,发送这个指令的程序就有可能被终止运行,这就是大部分常见的“非法操作”的由来,这样做的目的是为了保护计算机免遭破坏,如果外壳和内核的运行级别一样,用户一个不经意的点击都有可能破坏整个系统。
由于Ring的存在,除了由系统内核加载的程序以外,由外壳调用执行的一般程序都只能运行在Ring 3级别,也就是说,它们的操作指令全部依赖于内核授权的功能,一般的进程查看工具和杀毒软件也不例外,由于这层机制的存在,我们能看到的进程其实是内核“看到”并通过相关接口指令(还记得API吗?)反馈到应用程序的,这样就不可避免的存在一条数据通道,虽然在一般情况下它是难以被篡改的,但是不能避免意外的发生,Rootkit正是“制造”这种意外的程序。简单的说,Rootkit实质是一种“越权执行”的应用程序,它设法让自己达到和内核一样的运行级别,甚至进入内核空间,这样它就拥有了和内核一样的访问权限,因而可以对内核指令进行修改,最常见的是修改内核枚举进程的API,让它们返回的数据始终“遗漏”Rootkit自身进程的信息,一般的进程工具自然就“看”不到Rootkit了。更高级的Rootkit还篡改更多API,这样,用户就看不到进程(进程API被拦截),看不到文件(文件读写API被拦截),看不到被打开的端口(网络组件Sock API被拦截),更拦截不到相关的网络数据包(网络组件NDIS API被拦截)了,幸好网络设备的数据指示不受内核控制,否则恐怕Rootkit要让它也不会亮了才好!我们使用的系统是在内核功能支持下运作的,如果内核变得不可信任了,依赖它运行的程序还能信任吗?
这段概念是三年前写下的,而如今的网络世界,越来越多的木马后门在反病毒产品的围剿下消灭殆尽,就如同在一个密封的箱子里投入五大毒虫,让它们自相残杀,无论结局怎么样,总会有一方顽强的存活下来,而幸存的这只毒虫,就是最强最可怕的,只不过,反病毒产品并非每次都能成为存活下来的一方,而能够存活下来的非反病毒产品,必然是Rootkit。
这唯一幸存的毒虫所采用的技术迅速成了众人研究学习的重点,于是,Rootkit在短短几年内就走下了神秘的舞台,越来越“平民化”了,网络终于成为一个新的“艾滋病村”,在如此“平民化”的氛围里,Rootkit终于有了它“平民化”的名称: 驱动木马、驱动马、带驱动的木马,诸如此类,而它的本名,也被缩写为“RK”,多用于高人之间的交流称谓。
而普通上网民众,对这些东西的存在完全是概不知情的,或者,仅限于一个模糊的概念……
当其他类型的木马后门技术已可以轻而易举被歼灭以后,Rootkit技术就成了这场对抗赛的主力军,于是,为了存活,“驱动马”也开始出现不同的发展分支,在普通网民尚未察觉的时候,它们早已经“变异”出不同派系了……
一切的开端:SSDT Hook
在很早很早以前,一些用户突然觉得自己的机器存在异常,并经常有被人监控的感觉,于是使用杀毒软件进行全盘扫描,答案却是否定的,于是用户就信任杀毒软件,放心的去用了,直到有一天,“灰鸽子”木马在网上闹得轰轰烈烈,用户慌忙去下载了最新专杀工具,这一下,用户被吓坏了:我是什么时候被感染的灰鸽子?
普通网民第一次与“会隐形的木马”打交道,莫过于灰鸽子事件了,但是为什么“灰鸽子”无法被任务管理器和那时候的杀毒软件找到,甚至用户自己手动去查找,也是无功而返呢?这是因为,灰鸽子使用了最初的Rootkit技术:SSDT钩子。
而后,又有一些尚在雏形阶段的恶意流氓软件,也开始大玩“隐身”了,用户们是丝毫没有察觉的,除非一些恶意程序太过于张扬,但是,即使如此,他们也始终找不到异常情况发生的依据,任务管理器里没有、搜索文件没有、就连注册表监视软件,也没了回应……
造成这些现象的原因是什么呢?因为灰鸽子,以及后来出现的恶意程序,它们使用的交互接口,并非Ring 3用户层上的标准Win32 API,而是通过各种手段,例如驱动程序,进入到Ring 0内核层的Native API。
“Native API”(原生API)是Windows NT架构系统中真正工作的API,众所周知,Windows是一个通过大量API函数来实现程序功能的系统,然而,由于Windows是支持POSIX标准(可移植操作系统接口,Portable Operating System Interface)的系统,这就意味着,它除了能运行标准Windows平台程序(即Win32程序)以外,还支持少量其他平台上的程序运行,如OS/2。由于不同平台的程序功能实现方法差异,系统就必须分别为它支持的各个符合POSIX标准的程序提供相应的接口函数,如果根据这个思路去开发一套庞大而完整的接口函数调用,那就太不切实际了,于是,在NT架构系统上,开发者设计了两种不同性质的API接口层,一种被称为“用户态API”,它包括常见的Win32 API和POSIX接口API等,这些API运行在Ring3用户层上,构成了今天的Windows世界;而另一种是被称为“Native”性质的API,它们才是真正的系统API,通常运行在内核态上,实现真正的系统核心功能调用。同时为了实现POSIX,开发者还设计了被称为“子系统”(Sub System)的技术来将不同的系统环境区别开来,正常情况下,从系统引导到桌面时,我们就处于“Win32”子系统下,这时候起到作用的自然就是Win32 API。普通程序员平时接触到的几千个Win32 API,实际上都是通过几百个Native API的不同封装形式来实现的。系统厂商极少提供这些API的公开文档,是因为它们要比一般的函数难以应用而且可能发生变化,当程序员使用Win32 API时,最终的执行过程是在系统经过兼容性检查、错误处理、参数选项分离等一系列复杂转换后,才送入Native API进行处理的,Native API才是真正执行并反馈运行结果的主体,用户层的API调用只是一种封装形式罢了,例如fopen和CreateFile这两个Win32函数,它们的真正执行函数是Native性质的NtCreateFile,这就是rootkit可以让一般的进程工具不能发现自己的原因,因为它直接干涉了Native API的执行结果。
因为API还有这样复杂的故事,所以现在的恶意程序纷纷为了能最大限度提升自己的权限而变身rootkit性质程序,去“钩”这些原生API,而达到同等层次的安全检测工具和反病毒产品,也为了达到同样的效果而做了同样的事情,到了这个地步,安全产品和恶意软件在执行过程中已经没有区别了,唯一的区别是对用户和系统环境造成的后果差异而已。
既然大家都要控制到原生API层,那么他们的做法有没有共同点呢?答案是一定的,Windows作为一个规范的系统,就必须在原生API和用户层API之间存在一个标准的接口来实现数据传递,并限制用户使用其他不知名的操作来达到目的,这个接口由一个名为“ntdll.dll”的动态链接库文件负责,所有用户层API的处理都是调用这个DLL文件中的相关API入口实现的,但它只是一个提供从用户层跳转到内核层的接口,它并不是最终执行体。当API调用被转换为ntdll内的相关API函数后,系统就会在一个被称为“SSDT”(System Service Descriptor Table,系统服务描述符表)的数据表里查找这个API的位置,然后真正的调用它,这时候执行的API就是真正的原生API了,它们是位于NT系统真正内核程序ntoskrnl.exe里的函数。这一过程,就是系统服务的调用,例如外壳程序需要运行一个新的进程,那么它就会调用kernel32.dll导出的API函数CreateProcess,接下来就是kernel32.dll内的执行过程,实际上它只是把这个请求又包装了一下,变形为自己发出的参数,去调用ntdll.dll里导出的NtCreateProcess函数,然后ntdll.dll通过一个中断请求int 2Eh(Sysenter)进入内核态,并把我们最初的新建进程请求转换为“服务号”一起传递过去,到了内核的世界里,在正常手段下对API的调用都需要先通过一个函数地址描述表的转变来实现,SSDT就是这个表,它记录了一个庞大的地址索引,内容为几百个原生API在内核中导出的地址位置,除此之外还有一些有用的其他信息,在这个例子里,系统根据SSDT里记录的服务号与函数对应关系来确认我们要使用什么函数,以及这个函数在内核中的位置信息,最终实现功能调用,函数执行完毕后再把结果通过ntdll接口一层层传递回去,直到发出请求的程序收到一个表示处理结果的状态代码,这一次系统服务的调用过程就结束了。
由于上述原理,无论是恶意程序还是反病毒产品都会优先考虑把SSDT的内容给篡改以达到效果,简单的说,例如一个恶意程序把SSDT里对于获取进程标识的服务号对应的原生API地址修改为指向自己位于Ring0层的驱动入口,那么每次系统执行到这个函数时,都会由于SSDT的错误引导而进入了作者指定的服务模块中,就会导致相关的操作请求和参数被这个第三方模块记录和篡改,于是各种奇怪的现象就会发生了,就拿隐藏自身进程的rootkit技术来说,其原理就在于通过篡改SSDT里枚举进程的原生API服务号先指向自己的模块,再由自己的模块另行传递到真正的系统服务上(如果没有这一步操作或者操作错误,那么这个对应的系统服务就会作废甚至引发系统崩溃),并对真正的系统服务返回的数据进行加工处理,如删除带有自己进程名的数据,那么最终返回的数据里自然就“看不到”这个进程了。
通过操纵SSDT,以这个技术维生的Rootkit嚣张跋扈过一段时间,无论是木马后门还是流氓插件和恶意软件。在幕后挣钱的作者们也结结实实的过了个肥得流油的好年,然而好景不长,Anti-Rootki t(反Rootkit,即“ARK”)的概念被提出了,ARK工具也诞生了,如国产的IceSword、超级巡警等。此类ARK工具的运作原理和Rootkit大相径庭,它们也是通过驱动模块将自身投入系统内核中,从而达到了与Rootkit们平起平坐的公平竞争地位,然后,位于用户层的程序主体和进入内核态的驱动模块同时产生一个相同的查询API,例如枚举当前系统进程列表等,由于Rootkit的存在,用户层的程序主体最终得到的数据会比驱动模块返回的数据少那么几个——很明显,Rootkit驱动拼命要隐藏起来的用户层程序就此暴露,不打自招了;而同时,ARK还能将当前SSDT服务号指向的函数幕后的执行主体找出来,如果某个服务号指向的函数对应的执行主体不是NTOSKRNL.EXE(XP及以上系统中,某些机器是ntkrnlpa.exe),则可以断定该服务号有问题了。超级巡警以及后来的ARK更是直接提供了“一键恢复”功能,只需用户鼠标轻轻一点,所有第三方程序在SSDT挂住的钩子纷纷“脱钩”,短时间内就把RK布下的层层障碍给解除了,在一段时间内RK的势头迅速被压了下去,短暂的世界太平,短暂的,恩。
对于SSDT Hook,现在的所有Anti-Rootkit工具都能轻易找出并解除它的钩子(脱钩,Unhook),如IceSword、RKU、超级巡警等。
运行IceSword,首先点击“进程”,观察这里是否存在红色标记的进程,如果有,说明你的系统里绝对存在SSDT Hook,那红色的进程正是被底层驱动隐藏起来的文件,将它的具体位置记下来,并将其终止。
现在点击进入SSDT列表,会发现一些被红色标注出来的行列,记住它的“当前服务函数所在模块”,这个就是实施SSDT Hook的底层驱动文件。
然后,使用超级巡警切换至高级模式,将SSDT恢复为初始状态,它的所有防御就被解除了,现在直接查找刚才记录的文件去删除吧。
进一步试探:Shadow SSDT Hook
RK作者不甘心,无论是出于技术上的抗争还是利益上的损失,反正,ARK既然让我丢了面子或瘪了钱包,那么,“有朝一日龙得水,定叫长江水倒流!”,一些人开始尝试研究破解Anti-Rootkit工具,誓与之抗争到底,另一些人,则开始了新的探索,最终,双方都有了成效:首先,pjf的大作IceSword被成功反汇编了,虽然得到的并不是最初的C语言代码而是汇编语句,但是对于研究Rootkit的人来说,汇编在他们眼里,就如同看网络小说一样轻而易举,很快,就有人识破了作者的检测逻辑,可以绕过IceSword以及其他采用类似检测方法的工具的Rootkit就此诞生,甚至一部分RK已经开始反过来监控ARK,一旦相应ARK的驱动被加载,立即开始玉石俱焚——将用户机器弄成经典的蓝屏死机,不明就里的用户在几次与蓝色屏幕对望后,通常都会无奈的放弃;而另一种蓝屏则是更深层次的问题导致的,下面会提到。
而探索另一个方向的研究者们,也传来了捷报:Windows系统里,除了那个大家都在玩的SSDT(KeServiceDescriptorTable)以外,还有一个隐藏得非常深入的类似SSDT结构的数据段在同时工作着,它被称为“Shadow SSDT”(SSDT映射),这个“KeServiceDescriptorTableShadow”功能并未从系统内核中导出,但是通过外联的系统级别调试器,却看到了它的踪影。Shadow SSDT的作用和SSDT本身差不多,只不过它主要是提供一些基于图形用户界面(GUI)下的系统服务函数,并保存了一份与SSDT相同的服务列表,当然,这也是提供给基于GUI下的程序调用的。Shadow SSDT被安排在win32k.sys中,非常少文献提及它,因此这几乎是个被人遗忘的角落,Rootkit作者们很快就发现,控制这里也能达到一定的效果,因为Shadow SSDT同样具备了SSDT的所有功能,只不过是要利用的时候多了一些步骤而已,于是RK又有了新的玩法,这一次,轮到ARK傻眼了,那时候ARK根本没有做到Shadow SSDT这一步,于是,只钩住Shadow SSDT的Rootkit们得以无法无天的生存下去,任由用户怎么发现恶意程序怎么恢复SSDT都好,始终都是影响不到此类Rootkit!
这个情形,一直到具备了Shadow SSDT检测功能的ARK工具出现才结束,例如大名鼎鼎的RootKit Unhooker(RKU),它那强大的SSDT以及其Shadow检测脱钩功能,帮助许多人解决了这些新生的捣蛋鬼,于是,Rootkit作者们又开始寻求新的生存之道。
此类Hook由于出现得比较晚,很多当初流行的ARK都没有涉及这块,所以,我们只能使用RKU、狙剑等工具对其进行操作。
运行RKU(Rootkit Unhooker),它是英文软件,但是操作十分简便。点击“Shadow SSDT”,如果系统中存在Shadow SSDT Hook,你会发现软件底部状态栏里“Services/Hooked”不再是“xxx/0”的状态,同时相应被Hook的函数显示行里,“Hooked”一栏为“Yes”,现在记下这个文件的位置和地址,然后直接点“UnHooked ALL”,接下来,去找文件删除吧。
逼近顶峰:Inline Hook
世界上最荒谬的事情是什么?是顺着被人故意弄乱方向的路牌,往错误的方向走了好远都没察觉到有问题?还是被朋友恶作剧的将男女洗手间的标识换了位置?如果有天去造访寺院,却发现里面居然是清一色的道士在念经,你一定会惊呼,这简直太荒谬了!
在狂热的Rootkit领域里,类似的荒谬正在散布开来,那就是高级的Hook形式——Inline Hook。
在最初的运作流程里,所有被设置了挂钩的函数操作,最终还是要回到原始功能模块内处理的,毕竟第三方程序作者不是Windows系统编写者,为了保证系统的正常运行,最明智的做法当然是让被拦截的相关函数请求在经过自己编写的模块的层层检测并发现无害以后,立即将这个即将进行正常工作的请求原封不动的送到它该干活的地方去,以便系统完成整个工作流程,所以大家都在打SSDT等地方的主意,就是为了在这条必经之路上插上一脚,力求能绊倒那些看着不顺眼的路人。而现在,路上出现会砍脚的保安了,怎么办,难道玩不下去了吗?然而,迎接挑战正是每个研究者的兴趣所在,于是,荒谬的念头带出了可怕的技术,这就是Inline Hook。
其实,Inline Hook早就作为一种高级的Hook技术存在了,在用户层上的一些特殊程序如游戏外挂等,为了获得最完整可靠的数据,它们都不再采用错误指路牌的方法来将数据转移了,因为这样很可能会因为触发程序编写者针对此问题而设置的处理程序,最终功亏一篑。那么,怎么样才能让这个处理程序不能达到触发条件呢?那就是千万别去钩这个程序,但是如果不钩住程序,又该如何取得相关数据呢?在这样的思考模式下,一种新的钩子技术诞生了:它虽然也在玩钩子,但是它却不是来钩目标程序的,而是将系统里相应的API函数给虏了去,由于任何普通程序作者对系统API都是绝对信任的,于是,当他们的程序请求调用相关API并将参数一同发送过去时,由于提供这个API的相应模块被钩住了,它的“先知”——布施钩子者就抢先一步得到了数据内容,接下来就得看作者的编程功底来决定程序的生死了,因为作者并不能自己写出相应的系统函数,他就必须得设法将数据送回原函数执行模块里去,这一步稍有差错,就会导致调用这个API的程序崩溃退出。
正因如此,Inline Hook是一种相对一般Hook而言更复杂的技术,除非作者有较深的编程功底和对系统的了解,否则冒冒失失就大量使用这个技术是很容易出问题的,不仅受害者不好过,攻击者也无法取得他所需数据,得不偿失。
既然在用户层(Ring 3)上使用Inline Hook都要如此注意,那么在Rootkit的世界里有没有人吃螃蟹呢?答案是一定的,当钩住SSDT和Shadow SSDT的途径都被堵死以后,Rootkit技术终于向Inline Hook迈出了一步。
设想一下,当所有检测工具都在虎视眈眈SSDT这个关口时,某个Rootkit早已用自己的函数把系统内核里的敏感函数给替换了,当用户层的函数操作请求通过正常的SSDT找到相应内核态函数的执行主体时,却不知道这个执行主体早已被Rootkit冒名顶替了,那么情形会是怎么样的呢?虽然所有检测工具都报告情况正常,但是机器内其实早已被Rootkit安家,如果这个Rootkit预置了在某个时刻进行破坏行为的逻辑,那么用户直到系统出问题的那一刻,都还不知道究竟发生了什么事情!
位于Ring 0的Inline Hook是十分隐蔽的,除非研究者对系统了解较深,否则他想破了头也不能找出原因所在,更别提连杀个进程的概念都很迷茫的普通用户了。但是使用Inline Hook是必须付出代价的,由于内核的复杂性,尤其因为位于这一层的函数是所有程序都必须频繁调用的,很多时候如果设钩者没考虑周全,导致某个已经Inline Hook的函数被意外的直接调用,就会导致严重后果。所以,使用Inline Hook的Rootkit能否正常稳定的工作,是与作者的水平连接得十分紧密的,一个不成熟的用户层Inline Hook程序大不了就是跟着它要监控的程序一起引发内存错误导致非法操作异常退出,仅此而已,但是到了系统核心层,这里可没有任何错误检测模块来保证你的程序在做出会导致内核崩溃的事情之前就赶紧将它终止——这已经是最底层了,一个错误的内存读写都会直接引发内核级别的崩溃,即我们俗称的“蓝屏死机”(BSoD,Blue Screen of Dealth)。于是,不成熟的Inline Hook Rootkit的代价就是系统变得及其不稳定,在用户看来,电脑表现出来的症状就是莫名其妙的非常容易蓝屏,这就是技术不成熟的Rootkit导致的后果,只不过,这个代价是由受害的用户来承担的。
不过,目前能流行开来的Inline Hook Rootkit,基本上都是已经在开发者的机器上经历了无数次蓝屏考验后才出场的,所以通常情况下,用户并不会因为这些Rootkit的存在而频频蓝屏,并且,它已经成为当前Rootkit的主流技术。
对付Inline Hook,无论是狙剑、RKU还是Wsyscheck都可以做到,以狙剑为例,点击程序主界面的“扩展功能”,然后点击“SSDT检查”,你会突然有眼花缭乱的感觉,所以请点击右键——“筛选可疑项”,让它仅仅把异常部分显示出来(注意那个SnipeSword.sys,它是狙剑自身的驱动,不要弄错了),如果系统存在异常,“HOOK类型”里会列出相关说明,如HOOK、Inline-Hook等,首先可以尝试右键选择“恢复所有HOOK”,然后刷新一次,如果仍然列出异常项目,就得在相应的项目列上点击右键选择“恢复选定的Inline-HOOK”了。
紧紧缠绕的寄生藤:FSD Hook
随着RK与ARK的斗争进展,SSDT Hook(包括Shadow Hook)的道路被清理了,Inline Hook也被揪出来清理了,但是一些用户惊讶的发现,他们仍然无法删除这些已经暴露在眼皮底下的文件,这是为什么?
在解说这个问题之前,我们先来了解一些概念。为了让用户敲打键盘、点击鼠标、插入U盘等就能直接进入计算机的世界,操作系统在幕后是做了相当多的工作的,这些在底层运作的功能层层汇聚,最终建立出一个可用的操作平台,其中,负责管理磁盘数据和文件读写的部分被称为“文件系统”(File System,FS),其中,Windows系列操作系统是采用IOS(Input/Output Supervisor,输入输出管理程序)技术进行文件系统管理的。它接管所有的存储设备,如硬盘、可移动式磁盘、光驱等。
IOS是一种层次结构的管理方案,展现在用户层上的是各种应用程序的读写操作,其下一层紧接着的是被称为“可安装文件系统”(Installable File System,IFS)的接口层,这一层是以下各层的最终汇聚,通俗点说,也就是我们在屏幕上看到磁盘盘符、光驱盘符、U盘盘符、网络磁盘映射盘符等图标并对它们进行操作的由来。继IFS以后,就是各种文件系统驱动所在的层,即“FSD”(File System Driver,文件系统驱动),这一层直接与IOS连接,用于接受并处理属于自己任务分派内的数据;FSD下一层直达IOS,而到了IOS的下一层,数据就开始往硬件化发展了。
而这次Rootkit的目标,就是到达IOS之前的最后一层:FSD。
FSD在Windows系统中属于开放给编程人员可接触到的最深入的一块区域(再往下就是操作系统自身提供的驱动和硬件厂商的事情了),所以,这一层的权限是很高的,控制了这个层次,开发者就能掌握到最多最全面的文件读写操作控制,于是,当所有的道路都被Anti-Rootkit工具阻挠后,Rootkit作者开始反抗,方法是阻止他们的工具将揪出来的Rootkit直接歼灭。
FSD并非绝对禁地,在这之前,反病毒厂商和磁盘数据加密厂商早就在这一层里专研了,一部分人致力于编写自己的FSD,而更多的人,是通过编写FSD Filter Driver(文件系统驱动过滤器)来达到目的,以便从中析出它们敏感的数据来进行其他工作,而Filter驱动的一个要点就是钩住FSD,即“FSD Hook”。当FSD被你掌握后,你就可以通过操纵它的数据来控制别人的文件读写请求,对于Rootkit来说,它们可以将一些敏感文件如自身驱动程序文件、用户层相关文件等设置为除了它们自己以外的程序都无法对其进行读写的效果,到了用户层,直接反映出来的就是无法对其进行编辑、改名和删除。
用了这个技术,Rootkit作者们又可以偷笑了,因为即使用户用各种手段找到了它并将其进程终止,他也无法操作那些被保护起来的文件。
只是,钩子始终是钩子,总会有人去脱钩的,在克制FSD Hook技术的ARK工具出现后,一部分人面对着十分难以操作的FSD而放弃了,因为到了这一层已经非常容易导致系统不稳定了。
而一些人,仍然走了下去。
如何清理这个类型的Rootkit呢?以最容易操作的Wsyscheck为例,首先运行Wsyscheck(你会发现一个有趣现象:IceSword无法检测到Wsyscheck的Hook,因为它用的技术是Inline Hook和FSD Hook),点击进入“内核检查”,选中“FSD检查”,留意“代码异常”项里是否有标注为“Yes”的项,如果有,请在界面里右键点击,并选择“恢复所有函数”。Wsyscheck的进程列表并非使用IceSword一类的逻辑,所以如果你看到存在红色的列表也不要太过于紧张,它只是表示这个程序是没有系统签名验证、且类型特殊(如服务、加载驱动等)的应用程序而已,并非是IceSword这样的“坏人标识”。
产于极端的终极技术:FSD Inline Hook
Rootkit到了FSD Hook这一层,对系统造成的影响已经相当危险了,然而,由于出现了对抗的工具触动了某些人的利益,终于,一个著名的流氓软件吃了这只大家都会因为良心不安而不去触碰的螃蟹——FSD Inline Hook。
在及其重要敏感的FSD环境下放钩子本身就是一件要求很高的事情,而用自己的函数去替代这个雷区的系统函数,更是被很多人认为是严禁操作的事情,而现在,真的有人带头违反了,以后的局势又将如何呢?
所以,将CNNIC列为当前流氓软件作者的所有研究目标都不过分,因为CNNIC身上,就具备了多种高级技术,只可惜,全都没有用于正道。
Inline Hook的概念我们在前面已经说过了,现在主要说说这个Rootkit的行为以及后果。
也许是CNNIC的开发者对于自家产品频频被删除而恼怒了吧,这次最新发布的程序中,FSD Inline Hook终于出现了,它直接将操作系统厂商编写的相关功能使用自己的函数去取代了,而搞过FSD开发的人都知道,这一层的功能函数对硬件平台、系统版本是具有高度依赖性的,每个操作系统采用的函数都会有些许差异,但是操作系统厂商并不是制作通用的FSD方案,更何况,这个标准就是他们自己提出来的,所以这些变动对他们而言都是无伤大雅的,但是对于第三方厂商来说,他们缺少必要的开发文档(微软并未公布任何涉及FSD Inline Hook技术文档,也不鼓励开发者这样做)和齐全的硬件测试平台,所以,在不齐全的操作系统环境和硬件配置下实现的技术,必然很容易就导致受害用户直接欣赏到赏心悦目的蓝屏。
CNNIC必然清楚这点,但是,他们什么也不顾了。而且,CNNIC的技术水平果然也没达到稳定的水平,在被CNNIC安家的系统里,用户只要运行IceSword检测,就会直接导致蓝屏,这是因为它们都同时钩住了一个底层函数,但是下钩的位置存在些许偏差,例如,一个钩住了头部,一个钩住了屁股,于是内核受不了这很黄很暴力的行为,而直接崩溃了。
但是,毕竟已经有人起了头。以后的Rootkit世界将会变成什么样子,谁也不知道。
要消灭CNNIC以及采用FSD Inline Hook技术的Rootkit,首选应该是360安全卫士,但是如果出现了360安全卫士也未加入识别的Rootkit,用户就得使用“狙剑”了,解决方法与前面提及的大同小异,只需要对其“脱钩”就可以了,关键在于,用户还得留意Rootkit的用户层程序是否也使用Hook,如线程注入等。
RK多了,ARK也多了,这是好事还是坏事呢?答案自然是后者,无论是RK还是ARK,它们都必须进行同一个行为,就是进入系统内核层次并达到目的,于是不兼容现象往往会发生在几个ARK之间,例如,在运行了狙剑后,Wsyscheck经常会直接报错退出,而如果用户在开启了Wsyscheck的情况下运行IceSword,他将会有很大几率看到那蓝底白字的屏幕。
三. 结语
虽然到处都在提倡和谐网络的普及,但是,“健康上网”仅仅是指代那些黄赌毒而已吗?在利益面前,开发者的正义感越发渺小起来,我们的网络世界,是被瘟神紧紧跟随着的。技术的斗争越发激烈,但是用户的电脑知识是不会跟着时代发展而自动填充的,最终,大众上网的人民成了这一切技术较量的受害者。
这个荒谬的发展方向,何时才能休止呢?
主机防御系统体系简介
新一代的系统保护神
——主机防御系统体系简介
作者:小金
一. 与流氓木马说再见
现在是深夜时分,网民周颖正在打开某个刚认识不久的QQ网友发来的页面,这个网友自称是周颖喜欢的某明星的粉丝,两人聊得十分投机,最后,网友发来一个地址,说是自己收集的所有资料,周颖便不假思索的点击了。
在看到一个相册图片显示完的同时,周颖的电脑也弹出了一个窗口提示“CreateProcess请求被拦截”,宿主程序为“iexplore.exe”,执行对象为“123.exe”,周颖皱了皱眉,点击了“拒绝”按钮,随手把网页也关闭了。然后她气愤的在QQ上发了一句话:“刚认识就发木马,你也太不厚道了吧,你这人真无聊,不理你了!”,对方发来一个问号,周颖不再理会,直接就把这人拖进了黑名单。
经历了这么一件事情,周颖的好心情也被破坏了个殆尽,她气呼呼的和群里熟悉的朋友们发了一阵牢骚后就关机睡觉了。
在周颖盖上被子的时候,远方某处有个在百度黑客贴吧以“黑客高手”自居并收取高额“教学和工具费用”的小青年在迷糊的梦中被手机铃声吵醒,他刚接通电话,那边就传来了一阵骂声:“你收老子3000元做这个网页木马,说绝对私人流通躲避查杀100%好用的,老子今晚刚测试第一次就被个小丫头发现了!什么破玩意儿!三天内不退钱我就把你举报到网监科去!”,电话挂断了,小青年也被吼得睡意全无,他首先想到的是难道自己最得意的“免杀版”被反病毒厂商收集到了?可是在看到所有用作病毒测试的防毒软件均未提示发现病毒,莫名其妙,遇上不想付钱的无赖了……
网络有毒,这是所有人都必须认同的一点,即使你只是打开了一个网页看些新闻时事,没准你的浏览器就正在进行下载执行来自远方的未知木马的操作——只要你的系统有些相关安全漏洞没补上,这一切就发生了。
有人会说,不怕,我有杀毒软件,再多病毒也躲不过的——实际上,许多人的机器里就出现过木马与杀毒软件共享一片天下的事情,这是因为传统杀毒软件的局限性导致的,它们依赖于病毒特征码检测,针对这个特性,木马和病毒作者或第三方人士只需要做些特殊修改,就能使程序的特征码改变而无法被杀毒软件检测到,这就是大众意义上的“免杀版”;另一种情况则是“地下流传”的私人后门,由于大部分私人后门并非公众化产物,反病毒厂商不可能得知其存在,更不可能拥有其标本,也就没办法加入特征库查杀了。
很明显,周颖遇到的就是所谓的“免杀版”木马,而且入侵者尝试利用的或许更是针对浏览器的0day攻击,保护她的并不是杀毒软件,而是前不久经由朋友介绍使用的“主机入侵防御系统”软件。
二. 主机入侵防御系统的概念
主机入侵防御系统(Host Intrusion Prevent System,HIPS)是近几年出现并迅速发展的新兴产物,与传统意义的防火墙和杀毒软件不同,它并不具备特征码扫描和主动杀毒等功能,所以想用它来替换传统杀毒软件然后安枕无忧睡大觉的用户可以不必尝试了,主机入侵防御系统是不会区别正常程序和木马的,它只有一个动作,那就是让你了解一个进程的加载情况并让你决定这个进程能否运行,换句话说,系统的安全性取决于用户本身,因为主机入侵防御系统只是一种将系统控制权交给用户的防御体系。
操作系统是一个复杂而庞大的平台,程序的执行也不是简单的功能,在Windows环境里,当用户点击某个程序图标时,系统便产生一个消息由外壳程序传递到系统内核,由内核进行诸多初始化工作如分配内存、产生进程标识、协助加载程序运行所需的组件等,这些系统步骤都是可以由特殊程序进行监视并干涉的,只是通常情况下普通用户无法拥有这种待遇,而主机入侵防御系统则为用户提供了对于这个系统加载的监视和拦截功能。这个监视和拦截的过程被称为“防御”(Defend)。
目前主机入侵防御系统可提供三种防御:应用程序防御体系AD(Application Defend)、注册表防御体系RD(Registry Defend)、文件防御体系FD(File Defend),这三种体系合称为“3D”,根据实际情况,并非所有HIPS都提供了完整的3D体系,例如文件防御体系就经常被取消。
应用程序防御体系(AD)在大部分HIPS里属于最重要的功能,这个功能的优劣足以直接影响到系统安全。AD通过拦截系统调用函数来达到监视目的,当一个程序请求执行时,系统会记录该程序的宿主(即该程序的执行请求由哪个程序发出),在Windows里,用户启动的程序,其宿主为Windows外壳程序Explorer.exe,因为用户的交互界面是由该程序负责的,用户双击鼠标执行一个程序时,实际上就是通过Explorer.exe向内核传递的消息,于是它便成为用户程序的宿主;而并非所有程序都是通过Explorer.exe执行的,系统自身也执行着许多基本进程,这些进程几乎都由smss.exe所产生,而这些通过smss.exe产生的进程又能成为其它进程的宿主,如services.exe成为svchost.exe的宿主等,这些层层叠叠的关系被称为“进程树”(Process Tree)。基于这个原理,许多伪造成系统程序的木马其实很容易被发现,因为它们大部分通过系统启动项加载,而这个启动项是属于Explorer.exe负责的,于是木马们的宿主就成了它——csrss.exe居然由Explorer.exe加载运行,这本身就违背了系统设计的初衷。
让我们继续学习用户程序的执行过程,当程序执行的请求被系统捕获后,系统会产生一个创建进程的函数调用,称为CreateProcess,位于kernel32.dll,这个函数的功能是执行一些基本的初始化工作,然后将程序请求封装传递到内核接口ntdll的NtCreateProcess函数中,该函数把有关的参数从用户空间拷贝到内核并做进一步处理,直至最后新的进程被成功创建,而ntdll也只是个内核接口而已,实际的内核体是ntoskrnl.exe。程序员通过编写内核驱动拦截NtCreateProcess、NtCreateSection等函数就实现了对创建进程的控制,在这点上,病毒作者和安全专家做的事情都是相同的,只不过用来实现破坏系统安全作用的被称为Rootkit木马,用来保护系统的被称为“应用程序防御体系”而已。HIPS的“应用程序防御体系”也是通过驱动拦截实现的,只是它把创建进程的决定权交给用户。
在HIPS的监视下,当一个进程被请求创建时,用户层的应用程序接口函数CreateProcess被拦截并被获取调用参数来分析出程序的执行体和宿主等,而后HIPS将这个执行请求挂起(暂停执行CreateProcess及以后的步骤),并于桌面弹出一个对话框报告用户当前拦截的进程创建信息,其中包括执行体、宿主、被拦截的API等,最后等待用户决定是否继续让其执行。用户必须具备相关的进程概念,如桌面快捷方式和幕后调用的可执行程序实际文件名的对应关系,这样才不至于出现一头雾水的后果,用户的决定对于系统安全才是致命的,如果一个用户在双击“千千静听”后对着HIPS拦截的“Explorer.exe试图创建TTPlayer.exe进程”的报告感到不解,那么或许传统意义的杀毒软件更适合这类未入门的初哥。
HIPS的AD体系不仅能拦截到用户或某个程序产生的进程创建请求,它还能拦截到进程产生的所有操作,如DLL加载、组件调用等,这样我们也能用它来拦截一些DLL形态的进程注入,只要用户的基础知识达到一定程度,AD体系足以让你不再害怕大部分木马病毒的来袭,试想一下,如果用户在浏览网页时HIPS突然报告说浏览器进程“试图创建123.exe进程”、或者运行某些安装程序时HIPS拦截到该安装程序“试图创建1.exe进程”,只要用户选取了“拒绝执行”功能,这些潜在的木马就无法入侵用户的系统了——但是要注意一点,那就是木马本体已经被释放或下载回来了,只是它们无法被执行而已,HIPS不是杀毒软件,它不能阻止非法程序的下载和释放,更不提供自动删除文件的功能,它所做的,只是拦截进程操作而已,使用HIPS保护的系统安全取决于用户自身。
HIPS里还有个相当重要的功能是注册表防御体系(RD),众所周知,在Windows系统结构中,注册表一直扮演着一个重要角色,许多非法程序和木马也通过修改注册表达到许多黑暗目的,如主页修改劫持等,而木马等程序的自启动也是由注册表的启动项负责的,因此,要进一步确保系统安全的话,对注册表的监视保护是必须的,从很早以前就开始使用电脑的用户应该会记得当初流行的许多注册表监视工具,然而这些工具并不能帮助用户保护注册表,因为它们仅仅是位于用户层的程序而已,其调用的API函数也是经过层层封装返回的,在当前许多进入了核心层的木马面前,这些程序根本就是被耍猴的对象,要正确监视到真正的注册表操作,就必须进入核心层,抢先拦截到系统相关的底层注册表操作函数,这就是注册表防御体系的工作。
系统提供了一系列的注册表读写访问函数来实现用户层的功能,而这些API和之前提到的创建进程函数一样,也是一种对系统内核导出函数的封装传递,如果相关函数被驱动木马拦截,普通的注册表监视程序,包括系统自带的注册表编辑器也无法发现某些项目或执行相关操作,这就是“删不掉的启动项”的来由。
在内核层中,注册表的名称并非为Registry,而是“HIVE”(蜂巢),它的数据结构称为“Cell”(蜂室),这是最底层最不可被欺骗的注册表形态结构,许多高级的Rootkit分析程序都提供分析注册表的功能,实际上就是通过分别读取用户层返回和HIVE数据结构来判断对比系统中是否存在被恶意隐藏的数据项,分析HIVE文件是漫长的过程,这是对付高级隐藏时才不得以而为之的方法,而平时安全工具只需要拦截到内核层导出的操作函数如NtOpenKey、NtCreateKey、NtQueryKey等就可以了,这正是注册表防御体系要做的事情。
RD默认提供了对几个常见的系统敏感注册表项进行监视,如启动项、服务驱动项、系统策略项、浏览器设置项等,所有木马要自启动都必须经过启动项或服务驱动项的添加修改来实现,而要对浏览器进行劫持和主页修改就得通过修改浏览器设置项等,而这些操作默认都被RD视为敏感行为而拦截挂起,并弹出警告框报告用户该次操作的具体内容和发出操作请求的执行体,操作最终能否通过也同样取决于用户本身,由于它拦截了系统核心层导出的API函数,无论是木马还是用户程序的操作都逃不过法眼,从而实现了真正有效的监视和拦截。
最后是文件防御体系(FD),这个功能的作用是监视系统敏感目录的文件操作,如修改删除系统目录里的任何文件或创建新文件等,也可用来发现被驱动木马隐藏的文件本体,FD体系在许多杀毒软件里已经提供,一部分HIPS为了提高效率,并不具备FD,因为它相对要消耗的资源比较大,而前面的AD+RD+有一定经验的用户操作,就已经足够防止危害的文件操作产生了。
实现文件防御体系的要点同样也是拦截系统底层函数如NtOpenFile等,HIPS默认对系统敏感目录进行监控保护,一旦发现异常读写,则把相关操作挂起,并提示用户是否放行,FD不仅仅只有HIPS提供,其他安全工具如360安全卫士、超级巡警等也具备此功能,该功能运作起来要比前两者消耗的资源大些。
目前主流的HIPS软件有以下几款:
SNS(Safe and Sec Personal)、EQSecure、SSM(System Safety Monitor)、PG(ProcessGuard)、GSS(Ghost Security Suite)、SS(SafeSystem 2006)
国内公认较好用的HIPS是SSM,下面就以SSM为范本,对HIPS的实际操作进行解说。
三. SSM的使用
简介
System Safety Monitor,简称SSM,是一款对系统进行全方位监测的防火墙工具,它不同于传统意义上的防火墙,因此与任何网络和病毒防火墙都不相冲突。
之所以选择SSM,是因为相对于其他HIPS而言,SSM的操作比较简便,适应普遍大众的接受能力,且提供了中文版支持,其他如PG、SNS等操作相对烦琐了些,国产的S3在安全性上不如SSM,所以,对于一般环境的用户而言,SSM是最佳选择,而且由于HIPS不会与当前的传统防火墙产生冲突(不过要小心HIPS遭遇某些防火墙的误杀),用户在HIPS的基础上保留原有的防火墙也不失为一种更加强安全的选择——当然,这样的做法会消耗更多系统资源,如果硬件配置不够,建议根据个人实际能力来决定保留HIPS还是保留传统防火墙吧,开着HIPS照样被木马进驻的用户并非少数,而遭遇入侵的关键在于用户自己的操作过程,因为前面已经说过,HIPS仅仅用作行为拦截和警报而已。
SSM可由以下地址获得:http://www.syssafety.com/files.html
安装
HIPS并不强求用户安装时的系统环境是否染毒(文件型的除外,如熊猫烧香),也就是说,即使当前的环境中存在木马甚至Rootkit,在安装HIPS后照样能不慌不乱的对其进行限制操作,但是为了避免以后出现针对HIPS安装环境的木马,最好还是养成预先准备的习惯为好,经验告诉我们,“亡羊补牢”总是会晚一步的。
SSM的安装过程并不复杂,与一般的安装程序没什么差别,用户可以像安装QQ一样简单的完成它,安装完成后会提示重启以便SSM生效。
基本设置
重启完成后用户大概会习惯性的以为SSM会如传统意义上的防火墙软件一样在开机时出现在系统托盘里,那么SSM就让你失望了,它默认并不会随系统启动,首次运行还得用户手工进入开始菜单的程序组里寻找“System Safety Monitor”项运行它,在一些用户的系统上,SSM首次运行时还会出现svchost.exe与explorer.exe进程通讯被拦截的情况,如果遇到这种情况,用户必须在短时间内选择“允许”操作,否则会导致系统蓝屏。
首次运行SSM,用户会看到一堆英文,不用担心,进入Options,将里面的Language设置为Chinese,点击Apply Options即可,SSM就变成中文了,然后记得选中“自动启动”以确保SSM每次都能随系统启动。
对于高级用户,如果使用IceSword检查SSDT列表,会发现“祖国河山一片大红”的壮观景象,几乎所有的系统函数都被一个“safemon.sys”给“吸收”过去了,这是正常现象,这个文件就是SSM的核心驱动。
学习使用SSM
由于HIPS是一种特殊的系统防护程序,而并非传统的防火墙,这就注定了它不能像一般防火墙那样安装后定期更新一下病毒库就可以放任不管了,刚安装完毕的SSM仅对基本的几个系统进程给与信任关系,其他程序在首次运行时会被SSM拦截,这就需要用户手工运行常用的程序并设置规则为“永久允许”。
SSM会拦截所有进程创建的详细信息,并报告用户当前是什么程序试图执行另一个程序,并显示出所有运行参数,通常情况下用户自己请求运行的程序,其加载者为Explorer.exe,可以放心的通过执行。而一些由用户启动的程序在运行时可能会产生Hook调用和组件调用等,这些操作在通常情况下也是正常的。
如何判断一个程序的运行过程是否正常,关系到HIPS能否保护系统的关键,对于普通无经验用户来说,必须牢记以下几点:
•记住自己刚才运行了什么程序
•仔细观察被拦截的程序名和路径是否合法
•观察加载的DLL是否程序路径下或文件版权完整、且文件名不为胡乱组合字符
•一个浏览器程序在正常使用过程中(浏览网页)突然弹出执行另一个程序请求的,100%属于危险操作
用户只要至少牢记以上几点,就能防范80%的危险操作了,如果不慎允许了一些危险程序的执行,也不必惊慌,开启SSM的进程监控器选项,找到相应进程,点击右键选择“编辑规则”,然后设置为“阻止”即可,即使该危险程序有几个进程辅助运行,在HIPS面前也是小儿科罢了,因为被HIPS阻止运行的进程是永无翻身之日的,只会一个一个减少直到没有一个能够执行。
标准状态下,SSM仅开启了应用程序防御(AD)体系,要增加注册表防御(RD)体系,还得我们选择“模块”项,点中注册表,然后勾选“启用该模块”,从此注册表的敏感操作也就会被记录拦截了,默认情况下SSM已经提供了几个常见的敏感项,用户可酌情添加。
只要有木马程序试图操作敏感项目,SSM就会跳出“模块报警”并默认对其拦截操作,接下来又要用户自行判断是否放行该操作。与上面提及的一样,用户要记住执行该注册表操作的程序是否自己指定的,否则就不要通过,宁可错杀一个,也不要放过任何自己不敢保证的程序。
与注册表操作监视的形式,SSM也提供了服务监视,这对于一些通过设置服务达到隐秘启动的木马和Rootkit来说可谓灭顶之灾,那么这里该如何判断呢?同样的道理,不是自己运行或安装某个值得信任的工具时弹出的提示以外,一律不要允许!
SSM属于HIPS类程序中最简便的一款,通过使用和熟悉它,用户可掌握基本的HIPS知识,以便为日后换用更高级的HIPS做准备。
四. 结语
在木马和病毒横行的今天,已经难以有一款安全产品的出现足以让用户们产生眼前一亮的感觉了,HIPS类产品的问世解决了大部分安全专家和有经验用户头痛的防毒问题,然而美中不足的是,HIPS类产品距离大部分普通家庭用户仍然太远,其相关的一些操作需要用户具备一定的系统知识方可使用,就在一定程度上阻碍了HIPS的普及,这个尴尬的门槛,广大用户什么时候才能跨过去呢?是将HIPS的所谓“操作难度”降低、增加自动操作功能,使其最后沦为传统的杀毒防御产品一类的地步,还是让用户学习一定的计算机知识,以跨过这种在具备一定经验知识的用户眼里不足畏惧的所谓“门槛”?无论选择哪种,这都是个难题……
文件捆绑技术
一、眼睛,我凭什么相信你?
某天,QQ上有朋友给小白发了个编译成EXE文件的精彩Flash,Flash的确很好看,把小白逗得哈哈大笑。可是才过一会儿,他就笑不出来了:光驱不停弹出、鼠标乱跑、文件被删除……在他手足无措的时候,电脑突然重启,系统彻底瘫痪。
这是出现在许多描写黑客入侵的文章不约而同采用的“经典”题材,有朋友看了觉得奇怪:一个Flash文件都会造成这么大破坏?那我怕怕,我不看Flash了……
有时候我真不得不佩服某些朋友举一反三未雨绸缪的态度,同时也理解他们的害怕,是啊,谁能告诉我,眼前的文件到底是什么?但是也不要太过于紧张了,留意那些文章后面一般都会有的说明:“原来这个Flash被捆绑了木马。”
可是另一个问题又来了:什么是捆绑?
二、步入文件捆绑——从自解压文件说起
提起文件捆绑,许多朋友都会邹眉头,可是提起压缩文件,相信不会有人感到陌生。不知道大家有没有注意过一般压缩工具都会带的一个功能:生成自解压文件。这样压缩出来的文件是一个可执行文件,运行它就释放出整个压缩包了,有这样一个功能的确方便了用户,一些安装程序也是把自身做成自解压文件,可见这个方法的普遍性。
产生一个自解压文件的步骤如下:
1.把所有文件进行压缩编码,合成为一个普通压缩包
2.压缩工具产生一个文件外壳,写入压缩包的文件信息
3.把压缩包封装进这个文件外壳里,最终产生的可执行文件就是我们要的
一个自解压文件就是这么简单,那么,它与文件捆绑技术有什么关系呢?最大的关系就在于文件外壳。自解压文件和捆绑程序都是给原来的文件加了一个文件外壳,而它们的区别在于编码、用途、运行方式。
让我们先理解文件捆绑的概念:有一个可执行文件,它外表看起来并没有什么不妥,图标、把那版权也没问题,但是当你运行它的时候,它秘密分解成多个文件,只让其中一个或多个显示出来(通常是正常的,例如Flash),而其他程序(有害的)都是偷偷运行,让用户在不知不觉中受到侵害。实现这种“母鸡带崽”的技术就是“捆绑”(Bind),其实它不神秘,自解压文件就是一个光明正大带崽招摇过市的文件捆绑人员。
但是我们不能把自解压文件称为“捆绑”,为什么呢?现在,来看看一个捆绑文件是怎么产生的:
1.文件捆绑器产生一个文件外壳,把用户选择的可执行文件数量、体积、运行方式写入这个外壳里
2.在这个文件外壳后部追加可执行文件的数据,每个文件之间可能有特殊区别符号。
3.根据用户设定的文件图标、其他配置信息重写资源段
就这样,一个危害人间的捆绑文件产生了,你能认出来吗?
说白了,文件捆绑就是把几个可执行文件合并在一起,当用户运行这个文件集合体时,管理集合体的分离代码自动把每一个文件分离出来并偷偷执行,我们只要用自解压文件的知识就可以理解它。
三、实战分析捆绑文件
1.文件捆绑
EXE Bundle是一款比较强大的EXE捆绑机(EXE Binder),它支持最多10个文件的捆绑,我把冰河控制端作为用户程序,其他一大堆后门作为后台运行程序,捆绑界面如图1。
最后生成一个程序,看看图标,还认识吗?不过看看体积……(图2)
2.分析内部
用eXeScope载入文件(图3),发现什么问题没有?文件头部冒出两个EXEB字段,资源段里出现多个打不开的字串表,估计这些表就是分别对应每个EXE的分段。不同的捆绑器会产生不同的文件头部,但是追加文件的方法都一样的。
太复杂了?那么现在用二进制编辑工具打开它,搜索ASCII字符“This”,看看你发现了什么:
在第二个“This”的上面,我们看到这个
====================================================
bundle.INI
[Data Files]
ExtPath=1
Attrib2File1=1
[Delete Box]
CheckBox7=0
[执行文件]
File1=1
[Name Files]
File1=bundle.exe
File2=G_CLIENT.EXE
File3=G_SERVER.EXE
File4=GetAdmin.exe
File5=WinS.exe
File6=server.exe
File7=HAll.exe
File8=
File9=
File10=
File11=
======================================================
这是一段配置文件,显然,它作为一个分界线把文件外壳与文件集合体分开了,不同的文件捆绑器产生的信息不同,不必太计较这个,继续往下看:
1.G_CLIENT.EXEMZP
2.G_SERVER.EXEMZP
3.GetAdmin.exeMZ
4.server.exeMZP
如果你研究过一个程序的内部,就会知道我们查找“This”的原因:这是Windows下程序在DOS环境下运行显示的出错字符串,位于程序的头部。而这些“*****MZ”就是每个程序的起始段。
继续找下去,所有捆绑文件的头部都被发现了(图4),但是在最后一个程序后面找不到多余代码了,所以可以证明文件捆绑器是把自己放最前面,其他文件都塞后面的。
3.小结
分析这个捆绑文件可以得知,文件捆绑器仅仅把程序代码追加到文件外壳的尾部,并且改写它的配置信息,对程序代码并没有做任何编码处理,因此文件体积会相对扩大。
所以,可以对文件捆绑技术下个简单的概括:所谓文件捆绑,就是把多个可执行文件合并在一起,运行时偷偷释放出来所有并全部执行。
四、教你几招——与自解压文件的区别、防范捆绑文件的方法
如果你看到这里已经大彻大悟,那么我的苦心算是没有白费,如果还迷糊,那就看这里的概括……
与自解压文件的区别:
首先让我们看看两种文件的结构图(图5)。自解压文件仅仅是在原有的压缩包上加了个解压缩的可执行文件头,捆绑文件则是另一种结构体。但是从运行结果上看,它们是相同的。
但是,如果要具体区分,它们仍有本质上的不同:
1.自解压文件是压缩所有文件,并且大部分仅仅做释放文件功能;捆绑技术是集合可执行文件,释放后全部运行。
2.自解压文件里一般只有一个头部,捆绑技术产生的文件一般有多少个程序就有多少个头部
3.自解压文件体积一般比原来的文件集合要小,捆绑技术产生的文件却要大一点点
4.自解压文件一般难以再处理,捆绑技术产生的文件可以再加壳、压缩。
如何防范捆绑文件?
1.不要随意打开别人给你的文件
2.用字处理软件打开文件,如果查找到多于2个的“This program”字符串,那它一定是捆绑文件(这几乎是万能药)
3.杀毒程序的监控(不如人工准确)
4.对于一些捆绑器产生的伪造Flash文件之类,只要用一款查看文件调用函数的工具打开,如果看到调用了wsock32.dll、winsock.dll之类的,必然是木马无疑
5.消除对捆绑文件的恐惧心理!要明确一点,它们只对可执行文件有效,不是随便一张图片都能捆绑的!
浅析本机API, 浅析本机API
此文只能说是一篇笔记,是关于本机API的.本机API是除了Win32 API,NT平台开放了另一个基本接口。本机API也被很多人所熟悉,因为内核模式模块位于更低的系统级别,在那个级别上环境子系统是不可见的。尽管如此,并不需要驱动级别去访问这个接口,普通的Win32程序可以在任何时候向下调用本机API。并没有任何技术上的限制,只不过微软不支持这种应用开发方法。
User32.dll,kernel32.dll,shell32.dll,gdi32.dll,rpcrt4.dll,comctl32.dll,advapi32.dll,version.dll等dll代表了Win32 API的基本提供者。Win32 API中的所有调用最终都转向了ntdll.dll,再由它转发至ntoskrnl.exe。ntdll.dll是本机 API用户模式的终端。真正的接口在ntoskrnl.exe里完成。事实上,内核模式的驱动大部分时间调用这个模块,如果它们请求系统服务。Ntdll.dll的主要作用就是让内核函数的特定子集可以被用户模式下运行的程序调用。Ntdll.dll通过软件中断int 2Eh进入ntoskrnl.exe,就是通过中断门切换CPU特权级。比如kernel32.dll导出的函数DeviceIoControl()实际上调用ntdll.dll中导出的NtDeviceIoControlFile(),反汇编一下这个函数可以看到,EAX载入magic数0×38,实际上是系统调用号,然后EDX指向堆栈。目标地址是当前堆栈指针ESP+4,所以EDX指向返回地址后面一个,也就是指向在进入NtDeviceIoControlFile()之前存入堆栈的东西。事实上就是函数的参数。下一个指令是int 2Eh,转到中断描述符表IDT位置0×2E处的中断处理程序。
反编汇这个函数得到:
mov eax, 38h
lea edx, [esp+4]
int 2Eh
ret 28h
当然int 2E接口不仅仅是简单的API调用调度员,他是从用户模式进入内核模式的main gate。
W2k Native API由248个这么处理的函数组成,比NT 4.0多了37个。可以从ntdll.dll的导出列表中很容易认出来:前缀Nt。Ntdll.dll中导出了249个,原因在于NtCurrentTeb()为一个纯用户模式函数,所以不需要传给内核。令人惊奇的是,仅仅Native API的一个子集能够从内核模式调用。而另一方面,ntoskrnl.exe导出了两个Nt*符号,它们不存在于ntdll.dll中: NtBuildNumber, NtGlobalFlag。它们不指向函数,事实上,是指向ntoskrnl.exe的变量,可以被使用C编译器extern关键字的驱动模块导入。Ntdll.dll和ntoskrnl.exe中都有两种前缀Nt*,Zw*。事实上ntdll.dll中反汇编结果两者是一样的。而在ntoskrnl.exe中,nt前缀指向真正的代码,而zw还是一个int 2Eh的stub。也就是说zw*函数集通过用户模式到内核模式门传递的,而Nt*符号直接指向模式切换以后的代码。Ntdll.dll中的NtCurrentTeb()没有相对应的zw函数。Ntoskrnl并不导出配对的Nt/zw函数。有些函数只以一种方式出现。
2Eh中断处理程序把EAX里的值作为查找表中的索引,去找到最终的目标函数。这个表就是系统服务表SST,C的结构SYSTEM_SERVICE_TABLE的定义如下:清单也包含了结构SERVICE_DESCRIPTOR_TABLE中的定义,为SST数组第四个成员,前两个有着特别的用途。
typedef NTSTATUS (NTAPI *NTPROC) ( ) ;
typedef NTPROC *PNTPROC;
#define NTPROC_ sizeof (NTPROC)
typedef struct _SYSTEM_SERVICE_TABLE
{ PNTPROC ServiceTable; // 这里是入口指针数组
PDWORD CounterTable; // 此处是调用次数计数数组
DWORD ServiceLimit ; // 服务入口的个数
PBYTE ArgumentTable; // 服务参数字节数的数组
) SYSTEM_SERVICE_TABLE ,
* PSYSTEM_SERVICE_TABLE ,
* * PPSYSTEM_SERVICE_TABLE ;
/ / _ _ _ _ _ _ _ _ _ _ _ _
typedef struct _SERVICE_DESCRIPTOR_TABLE
{ SYSTEM_SERVICE_TABLE ntoskrnl ; // ntoskrnl所实现的系统服务,本机的API}
SYSTEM_SERVICE_TABLE win32k; // win32k所实现的系统服务
SYSTEM_SERVICE_TABLE Table3; // 未使用
SYSTEM_SERVICE_TABLE Table4; // 未使用
} SERVICE_DESCRIPTOR_TABLE ,
* PSERVICE_DESCRIPTOR_TABLE,
* PPSERVICE_DESCRIPTOR_TABLE ;
ntoskrnl通过KeServiceDescriptorTable符号,导出了主要SDT的一个指针。内核维护另外的一个SDT,就是KeServiceDescriptorTableShadow。但这个符号没有导出。要想在内核模式组件中存取主要SDT很简单,只需两行C语言的代码:
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
PSERVICE_DESCRIPTOR_TABLE psdt= KeServiceDescriptorTable;
NTPROC为本机 API的方便的占位符,他类似于Win32编程中的PROC。Native API正常的返回应该是一个NTSTATUS代码,他使用NTAPI调用约定,它和_stdcall一样。ServiceLimit成员有在ServiceTable数组里找到的入口数目。在2000下,默认值是248。ArgumentTable为BYTEs的数组,每一个对应于ServiceTable的位置并显示了在调用者堆栈里的参数比特数。这个信息与EDX结合,这是内核从调用者堆栈copy参数到自己的堆栈所需的。CounterTable成员在free buid的2000中并没有使用到,在debug build中,这个成员指向代表所有函数使用计数的DWORDS数组,这个信息能用于性能分析。
可以使用这个命令来显示:dd KeServiceDescriptorTable,调试器把此符号解析为0×8046e0c0。只有前四行是最重要的,对应那四个SDT成员。
运行这个命令:ln 8046e100,显示符号是KeServiceDescriptorTableShadow,说明第五个开始确实为内核维护的第二个SDT。主要的区别在于后一个包含了win32k.sys的入口,前一个却没有。在这两个表中,Table3与Table4都是空的。Ntoskrnl.exe提供了一个方便的API函数。这个函数的名字为:
KeAddSystemServiceTable
此函数去填充这些位置。
2Eh的中断处理标记是KisystemService()。这也是ntoskrnl.exe没有导出的内部的符号,但包含在2k符号文件中。关于KisystemService的操作如下:
1 从当前的线程控制块检索SDT指针
2 决定使用SDT中4个SST的其中一个。通过测试EAX中递送ID的第12和13位来决定。ID在0×0000-0×0fff的映射至ntoskrnl表格,ID在
0×1000与0×1ffff的分配给win32k表格。剩下的0×2000-0×2ffff与
0×3000-0×3ffff则是Table3和Table4保留。
3 通过选定SST中的ServiceLimit成员检查EAX的0-11位。如果ID超过了范围,返回错误代码为STATUS_INVALID_SYSTEM_SERVICE。
4 检查EAX中的参数堆栈指针与MmUserProbeAddress。这是一个ntoskrnl导出的全局变量。通常等于0×7FFF0000,如果参数指针不在这个地址之下,返回STATUS_ACCESS_VIOLATION。
5 查找ArgumentTable中的参数堆栈的字节数,从调用者的堆栈copy所有的参数至当前内核模式堆栈。
6 搜索serviceTable中的服务函数指针,并调用这个函数。
7 控制转到内部的函数KiserviceExit,在此次服务调用返回之后。
从对SDT的讨论可以看到与本机API一起还有第二个内核模式接口。这个接口把Win32子系统的图形设备接口和窗口管理器和内核模式组件Win32k连接起来。Win32k接口一样是基于int 2eh。本机API的服务号是从0×0000到0×0fff,win32k的服务号是从0×1000到0×1fff。(ddW32pServiceTable认定win32k.sys的符号可用。)win32k总共包含639个系统服务。
2Eh的处理过程没有使用全局SDT KeServiceDescriptorTable。
而是一个与线程相关的指针。显然,线程可以有不同得SDT相关到自身。线程初试化的时候,KeInitializeThread()把KeServiceDescriptorTable写到线程的控制块。尽管这样,这个默认设置之后可能被改变为其它值,例如KeServiceDescriptorTableShadow。
Windows 2000运行时库
Ntdll.dll至少导出了不少于1179个符号。其中的249/248是属于Nt*/zw*集合。所以还有682个函数不是通过int 2eh门中转。很显然,这么多的函数不依靠2k的内核。
其中一些是和c运行时库几乎一样的函数。其实ntoskrnl也实现了一些类似C运行时库的一些函数。可以通过ddk里的ntdll.lib来链接和使用这些函数。反汇编ntdll.dll与ntoskrnl.exe的C运行时函数能发现,ntdll.dll并不是依赖ntoskrnl.exe。这两个模块各自实现了这些函数。
除了C运行时库外,2000还提供了一个扩展的运行时函数集合。再一次,ntdll.dll与ntoskrnl.exe各自实现了它们。同样,实现集合有重复,但是并不完全匹配。这个集合的函数都是以Rtl开头的。2000运行时库包括一些辅助函数用于C运行时候无法完成的任务。例如有些处理安全事务,另外的操纵2000专用的数据结构,还有些支持内存管理。微软仅仅在DDK中记录了很有用的406个函数中的115个函数。
Ntdll.dll还提供了另外一个函数集合,以__e前缀开头。实际上它们用于浮点数模拟器。
还有很多的函数集合,所有这些函数的前缀如下:
__e(浮点模拟),Cc(Cache管理),Csr(c/s运行时库),Dbg(调试支持),Ex(执行支持),FsRtl(文件系统运行时),Hal(硬件抽象层),Inbv(系统初试化/vga启动驱动程序bootvid.dll),Init(系统初试化),Interlocked(线程安全变量操作),Io(IO管理器),Kd(内核调试器支持),Ke(内核例程),Ki(内核中断处理),Ldr(映象装载器),Lpc(本地过程调用),Lsa(本地安全授权),Mm(内存管理),Nls(国际化语言支持),Nt(NT本机API),Ob(对象管理器),Pfx(前缀处理),Po(电源管理),Ps(进程支持),READ_REGISTER_(从寄存器地址读),Rtl(2k运行时库),Se(安全处理),WRITE_REGISTER_(写寄存器地址),Zw(本机API的替换叫法),<其它>(辅助函数和C运行时库)。
当编写从用户模式通过ntdll.dll或内核模式通过ntoskrnl.exe和2000内核交互的软件的时候,需要处理很多基本的数据结构,这些结构在Win32世界中很少见到。
常用数据结构
l 整数
ANSI字符是有符号的,而Unicode WCHAR是无符号的
MASM的TBYTE是80位的浮点数,用于高精度浮点运算单元操作,注意它与Win32的TBYTE(text byte)完全不同。
TABLE 2-3. Equivalent Integral Data Types
BITS MASM FUNDAMENTAL ALIAS #1 ALIAS #2 SIGNED
8 BYTE unsigned char UCHAR CHAR
16 WORD unsigned short USHORT WCHAR SHORT
32 DWORD unsigned long ULONG LONG
32 DWORD unsigned int UINT INT
64 QWORD unsigned _int64 ULONGLONG DWORDLONG LONGLONG
80 TBYTE N/A
typedef union _LARGE_INTEGER
{ struct{
ULONG LowPart;
LONG HighPart;};
LONGLONG QuadPart;
}
LARGE_INTEGER , * PULARGE_INTEGER ;
typedef union _ULARGE_INTEGER{
struct{
ULONG LowPart;
ULONG HighPart;}
ULONGLONG QuadPart;
}ULARGE_INTEGER, *PULARGE_INTEGER;
l 字符
Win32编程中PSTR用户CHAR*,PWSTR用于WCHAR*。取决于是否定义了UNICODE,PTSTR解释为PSTR或者PWSTR。在2k内核模式下,常用的数据类型是UNICODE_STRING,而STRING用来表示ANSI字符串:
typedef struct _UNICODE_STRING{
USHORT Length; //当前字节长度,不是字符!!!
USHORT MaximumLength; //Buffer的最大字节长度
PWSTR Buffer;}UNICODE_STRING , * PUNICODE_STRING ;
typedef struct _STRING{
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;}STRING, *PSTRING;
typedef STRING ANSI_STRING, *PANSI_STRING;
typedef STRING OEM_STRING, *POEM_STRING;
操纵函数:RtlCreatUnicodeString(),RtlInitUnicodeString(),
RtlCopyUnicodeString()等等
l 结构
许多内核API函数需要一个固定大小的OBJECT_ATTRIBUTES结构,比如NtOpenFile()。对象的属性是OBJ_*值的组合,可以从ntdef.h中查到。
IO_STATUS_BLOCK结构提供了所请求操作结果的信息,很简单,status成员包含一个NTSTATUS代码, 如果操作成功 information成员提供特定请求的信息。
还有一个结构是LIST_ENTRY,这是一个双向环链表。
typedef struct _OBJECT_ATTRIBUTES
{
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBDTES, *POBJECT_ ATTRIBUTES;
typedef struct _IO_STATUS_BLOCK
{
NTSTATDS Status;
ULONG Information;
}IO_STATUS_BLOCK , * PIO_STATUS_BLOCK ;
typedef struct _LIST_ENTRY
{
Struct _LIST_ENTRY *Flink;
Struct _LIST_ENTRY *Blink;
}LIST_ENTRY, *PLIST_ENTRY;
双向链表的典型例子就是进程和线程链。内部变量PsActiveProcessHead是一个LIST_ENTRY结构,在ntoskrnl.exe的数据段中,指定了系统进程列表的第一个成员。
CLIENT_ID结构由进程和线程ID组成。
typedef struct _CLIENT_ID
{ HANDLE UniqueProcess;
HANDLE UniqueThread;
)CLIENT_ID, *PCLIENT_ID;
想要从用户模式调用ntdll.dll中的API函数,必须考虑到以下四点:
1 SDK头文件没有包括这些函数的原型
2 这些函数使用的若干基本数据类型没有包括在SDK文件中
3 SDK和DDK头文件不兼容,不能在win32的c源文件包含ntddk.h中
4 ntdll.lib没有包括在VC的默认导入库列表中。
第4个很容易解决:#progma comment(linker,“/defaultlib:ntdll.lib”)
缺失的定义比较难解决,最简单的方法是写一个自定义的头文件,刚刚包含需要调用ntdll.dll中函数的定义。幸运的是,已经在光盘的w2k_def.h文件中做了这个工作。因为这个头文件将用于用户模式和内核模式程序,所以必须在用户模式代码中,#include<w2k_def.h>之前#define _USER_MODE_,使得DDK中出现而SDK中没有的定义可用。
数据库日常维护
数据库日常维护工作是系统管理员的重要职责。其内容主要包括以下几个部分:
一、备份系统数据
SYBASE 系统的备份与恢复机制保证了在系统失败时重新获取数据的可能性。SQL Server 提供了两种不同类型的恢复机制:一类是系统自动完成的恢复,这种措施在每次系统启动时都自动进行,保证了在系统瘫痪前完成的事务都写到数据库设备上,而未完成的事务都被回退;另一类是人工完成的恢复,这是通过 DUMP 和 LOAD 命令来执行人工备份和恢复工作。因此定期备份事务日志和数据库是一项十分重要的日常维护工作。
1、备份数据库
每一个数据库都应在创建之后卸出,从而提供一个装入基点。在此之后按排定的时间周期表卸出。比如每周五卸出数据库。对一般数据库系统卸出数据库周期建议为每周一次。
除了按计划周期卸出数据库之外,还需在每次运行没有日志的操作后卸出数据库。例如:
·每次强制地运行了 DUMP TRAN WITH NO_LOG (因为数据库的磁盘空溢出);
·每次用 sp_dboption 允许 select into/bulkcopy 做快速拷贝,或用 SELECT INTO 命令创建一个永久性的表,或使用了 WRITETEXT 命令。
卸出数据库的命令为:
DUMP DATABASE database_name
TO dump_device
database_name 是要卸出的数据库名称,dump_device 是卸出设备的名称。用系统过程 sp_helpdevice 可以获得设备的信息。
下面一条命令用来卸出数据库 my_db :
DUMP DATABASE my_db
TO db_bk_dev
2、备份事务日志
如果事务日志与数据库放在同一个设备上,则事务日志不应与数据库分开备份。master 数据库和小于 4M 的用户数据库就是这种情况。一般数据库系统的数据库和日志分别放在不同的设备上,因此,可以用 DUMP TRAN 命令单独备份日志。
备份事务日志的周期直接影响数据的恢复程度,因此建议每天备份。
备份事务日志的命令格式为:
DUMP TRANsaction database_name
[TO dump_device]
[WITH TRUNCATE_ONLYWITH NO_LOGWITH NO_TRUNCATE]
其中 database_name 是要备份事务的数据库名称,dump_device 是备份设备名称,仅当包含了 WITH TRUNCATE_ONLY 或 WITH NO_LOG 子句时,才可以备份到设备。
注意:如果总是用 DUMP DATEBASE (备份数据库及其日志),而不用 DUMP TRAN ,事务日志将不会刷新,而变得非常庞大。
对于 master 数据库和小型数据库每次运行 DUMP DATEBASE 之后应当运行 DUMP TRANsaction 命令刷新日志 。
下面一条命令备份数据库 db160 的事务日志到备份设备上:
DUMP TRANsaction db160
TO db_log_bk_dev
WITH TRUNCATE_ONLY
3、备份数据库及其日志间的相互作用
在至少卸出一次数据库前,卸出事务日志是毫无意义的。下图显示了备份数据库及其日志间的关系
如果在星期二下午5:01出现非硬件故障,需要做的所有工作是装入磁带5(参见下一节:数据恢复),由于磁带5是下午5:00刚备份的,因此只有备份和装入之间的一分钟内的数据损失。
但是,如果在星期二下午4:49失效会怎么样呢?在这种情况下,要装入磁带1(在星期五下午5:00的卸出)。然后,依次装入磁带2,3以及4。这样,系统将恢复到星期二上午10:00点的状态,星期二的大部分工作丢失了。此例显示了经常卸出事务的重要性。
二、万一系统失败时恢复数据库系统
如果用户数据库存储的设备失效,从而数据库被破坏或不可存取,通过装入最新的数据库备份以及后来的事务日志备份可以恢复数据库。假设当前的事务日志存在于一个并没有毁坏的设备上,带着 WITH NO_TRUNCATE 选项的 DUMP TRANsaction 命令卸出它。
要恢复数据库按如下步骤去做:
1、如果日志存在于一个分离的设备上,用带着 NO_TRUNCATE 选项的 DUMP TRANsaction 命令卸出被毁坏的或者不可存取的用户数据库事务日志。
2、用下面的查询检查设备分配已毁坏数据库的设备使用情况。必须为同一目的赋同样的空间块。
下面的查询显示了分配给数据库 mydb 设备使用和尺寸情况:
SELECT segmap,size FROM sysusages
WHERE dbid =
( SELECT dbid FROM sysdatabases WHERE name = “mydb”)
3、检查查询的输出。在 segmap 列的 ‘3’代表数据分配,‘4’代表日志分配。size 列代表 2K 数据块的数目。注意此信息的次序、使用和尺寸部分。例如,输出为:
segmapSize
——————–
310240//实际尺寸为:20M
35120//实际尺寸为:10M
45120//实际尺寸为:10M
31024//实际尺寸为:2M
42048//实际尺寸为:4M
4、用 DROP DATABASE 命令删除毁坏设备上的数据库。如果系统报错,用DBCC DBREPAIR 命令的 DROPDB 选项。
5、删除数据库后,用 sp_dropdevice 删除毁坏了的设备。
6、用 DISK INIT 初始化新的数据库设备。
7、重建数据库。用 CREATE DATABASE 命令从老的 sysusages 表拷贝所有的行,并包含第一逻辑设备。
对上例,命令为:
CREATE DATABASE mydb
ON datadev1=20,datadev2=10
LOG ON logdev1=10
8、用 ALTER DATABASE 命令重建其余入口。在此例中,在datadev1上分配更多的空间,命令为:
ALTER DATABASE mydb ON datadev1=2
9、用 LOAD DATABASE 重新装入数据库,然后用 LOAD TRAN 装入前面卸出的日志。
LOAD DATABASE 命令语法是:
LOAD DATABASE database_name
FROM dump_device
LOAD TRANsaction 命令的语法是:
LOAD TRANsaction database_name
FROM dump_device
卸出数据库和事务日志的缺省权限归数据库所有者,且可以传递给其他用户;装载数据库和事务的权限也归数据库所有者,但不能传递。
二、产生用户信息表,并为信息表授权;
系统维护人员的另一个日常事务是为用户创建新的信息表,并为之授权。创建表以及为表授权的方法已经在讲过,在此只将有关命令语法写出来。
·创建表的命令为:
CREATE TABLE table_name
( column_1 datatype [NULL NOT NULL IDENTITY],
column_2 ……
)
go
ALTER TABLE table_name
ADD PRIMARY KEY (column_list)
go
·删除表的命令格式为:
DROP TABLE table_name
go
·为表授权的命令格式为:
GRANT {ALLpermission_list}
ON table_name TO user_name
go
·收回权限的命令格式为
REVOKE {ALLpermission_list}
ON table_name FROM user_name
go
三、监视系统运行状况,及时处理系统错误;
系统管理员的另一项日常工作是监视系统运行情况。主要有以下几个方面:
1、监视当前用户以及进程的信息
使用系统过程:sp_who
说明:该命令显示当前系统所有注册用户及进程信息,如下表是某系统的信息。
SpidStatusLoginamehostnameblkdbnamecmd
—————————————————————
1RunningSascosysv0MasterSELECT
2SleepingNULL0MasterNETWORK HANDLE
3SleepingNULL0MasterDEADLOCK TUNE
4SleepingNULL0MasterMIRROR HANDLER
5SleepingNULL0MasterHOUSEKEEPER
6SleepingNULL0MasterCHECKPOINT SLEEP
从左向右依次显示:进程号、当前状态、注册用户名、主机名、占用块数、数据库名以及当前命令。
如果监视时发现进程总数接近最大连接数(用系统过程:sp_configure “user conn” 查看)时,应下掉不活动或无关进程,以保证系统正常运做;另外亦可监视非法用户或用户使用不属于自己使用范围的数据库等情况。
2、监视目标占用空间情况
使用系统过程:sp_spaceused
说明:该过程显示行数、数据页数以及当前数据库中由某个目标或所有目标所占用的空间。如下表是某数据库日志表的信息:
NameRow_totalreserveddataIndex_sizeunused
————————————————————
SyslogsNot avail32KB32KB0KBNot avail
日常要监视的主要目标有:用户数据库、数据库日志表(syslogs)以及计费原始数据表等。如果发现占用空间过大,对日志表要进行转储;对其他目标则应扩充空间或清楚垃圾数据。
3、监视 SQL Server 统计数字
使用系统过程:sp_monitor
说明:sp_monitor 显示SQL Server 的历史统计数字,下表是某系统的统计数字:
Last_runCurrent_runSeconds
—————————————————————
May 13 2000 1:27PMMay 13 2000 3:01PM5678
CPU_busyIO_busyIdle
—————————————————————
16(6)-0%0(0)-0%5727(5672)-99%
Packets_receivedPackets_sentPacket_errors
—————————————————————
21(17)100(97)0(0)
Total_readTotal_writeTotal_errorsConnections
——————————————————–
785(366)311(113)0(0)3(2)
上表依次给出该系统本次运行统计的上一次时间、本次时间、间隔秒数、CPU占用、IO占用、收发包情况、系统读入写出情况等信息
四、保证系统数据安全,周期更改用户口令;
为保证系统数据的安全,系统管理员必须依据系统的实际情况,执行一系列的安全保障措施。其中,周期性的更改用户口令是比较常用且十分有效的措施。
更改用户口令是通过调用系统过程sp_password 来实现的。Sp_password 的语法为:
sp_password caller_password,new_password [,loginame]
其中caller_password 是登录口令(老口令),new_password是新口令,loginame是登录名称。
萨科齐致信胡锦涛称支持中国统一
核心提示:4月26日晚,正在访华的法国总统萨科齐的特使、法国前总理拉法兰透露,萨科齐在让他带给胡锦涛主席的信中强调了三点:首先,萨科齐表示法中关系没有变化。其次,法国支持奥运会和世博会。最后,法国尊重中国统一问题,法国遵循一个中国政策。

拉法兰25日在北京出席中欧论坛。拉法兰此行肩负着修补中法友谊的重任。
东方网4月27日报道 “我想向中国的网友们发出一个邀请,请你们去我的博客看一看”。昨晚8时15分,正在访华的法国总统萨科齐的特使、法国前总理让-皮埃尔·拉法兰在北京和平宾馆文华厅举行记者见面会。他希望中国和法国的年轻人们增加相互的了解。
在回答记者提问时,这位“中国人民的老朋友”说:“友谊确实需要坚持,我们不能成天换朋友。”
“友谊确实需要坚持”
在昨晚的记者见面会上,工作人员首先向记者分发了写有拉法兰博客地址的纸条www.carnetjpr.com,记者随即打开,居然发现拉法兰最新一篇博文用汉语写成:“自1976年以来,我定期访问中国。我从来没有取消过,去中国的行程,即使在2003年‘非典’盛行期间。因此,我可以估量中国的发展,见证中国对外开放政策的进步……西方没有干涉中国统一的特权。”
2003年4月“非典”期间,时任法国总理的拉法兰面对国内外压力,毅然如期访问中国。他曾经引用法国文豪巴尔扎克的名言“力量的最好表现在于持之以恒”来形容当时的中法关系并鼓励中国战胜“非典”。
5年以后,当早报记者提及当时的情形,他依然微笑着说:“友谊确实需要坚持,我们不能成天换朋友吧。”他说,我和中国人民有很深的感情。
雨点掉在屋顶很快就消失
拉法兰透露,此次法国总统萨科齐在让他带给胡锦涛主席的信中强调了三点:首先,萨科齐表示法中关系没有变化,从戴高乐之后建立的关系没有发生变化,以后这种关系也有延续性。其次,法国支持中国开放政策,支持奥运会和世博会,让世界了解中国,法国支持中国的对外开放政策。最后,法国尊重中国统一问题。法国遵循一个中国政策。
“我回国后,要向萨科齐传达的信息是:中国领导人非常重视对法国的友谊;法中之间要全面贯彻战略伙伴关系;通过萨科齐总统向法国人民表达一个观点:没有人会伤害中法之间的关系。”他说。
拉法兰认为,在21世纪,中国将发挥首屈一指的作用,世界需要和平力量,而要实现和平需要通过多极才能实现,中国在和平力量中具有举足轻重的作用。拉法兰认为中国和平崛起是个好的信息。他第一次来中国是在1976年,拉法兰表示,看到中国发展变化感到很高兴,但是很多人在讲中国发展时,没有历史地看待中国发展变化。
“交流不可能引起不了解,只有无知才能引起不了解。”拉法兰认为,中法两国是战略性伙伴关系,不仅是历史上因为中法两国互相交流,而更多的是朋友关系,两国文明应该互相尊重,应该平衡地去看待不同的世界观。
在举行记者见面会之前,拉法兰访问了天津。在会见天津市市长黄兴国时,拉法兰表示,法国对中国的发展前景充满信心。他还参观了滨海新区的施耐德电气公司和空客A320项目。
对于目前中法两国关系,拉法兰认为,只是因为极少数人的问题导致,不是大多数法国人的态度。拉法兰说:“我本人对极少数人表示谴责,‘雨点掉在屋顶上很快就会消失。’”
记者会即将结束时,这位60岁的老朋友说:“法国喜爱中国!”
◇相关链接
拉法兰写于23.04.2008的中文博客
去中国之前想说的几句话
自1976年以来,我定期访问中国。我从来没有取消过,去中国的行程,即使在2003年“非典”盛行期间。
因此,我可以估量中国的发展,见证中国对外开放政策的进步。
中国的开放令全世界人民更好地了解中国,也使中国人民的生活得到了改善。
伟大的中国人民期待通过北京奥林匹克运动会,取得重大进步。他们更期望我们的友谊,而不是我们的说教。
北京奥林匹克运动会是中国与世界对话的成果。抵制便是中断对话,便是用关闭的态度来回应中国开放的战略。
不参与就是否定对话。
西方没有干涉中国统一的特权。
法国要表达的仍是我们法兰西共和国的基本原则:自由、平等、博爱。这一信息通过友谊的渠道,在“文化多元性”的范围内表达。“文化多元性”使中法两个古老文明团结在一起,互相尊重以便更好地互相理解。
世界和平需要法中友谊。
让-皮埃尔·拉法兰
法国原总理
参议员
法文原文:
Quelques mots avant de partir en Chine
Depuis 1976 je visite régulièrement la Chine : je n’ai jamais annulé un voyage, pas même en 2003 pendant l’épidémie du SRAS.
Je peux ainsi mesurer l’évolution de la Chine et constater les progrès de la politique d’ouverture au monde.
Cette ouverture permet aux peuples de la planète de mieux connaître la Chine, elle permet aussi une amélioration du niveau de vie du peuple chinois.
Ce grand peuple attend des progrès importants grâce aux Jeux Olympiques de Pékin. Il compte plus sur notre amitié que sur nos leçons.
Ces jeux sont le fruit du dialogue engagé entre la Chine et le reste du monde. Un boycott serait une rupture de dialogue. Ce serait une réponse de fermeture à une stratégie d’ouverture.
La chaise vide est la négation du dialogue.
L’Unité de la Chine n’est pas la prérogative de l’Occident.
Le message de la France reste celui de notre République : Liberté, Egalité, Fraternité. Il s’exprime par le canal de l’amitié et dans le cadre de « la diversité culturelle » qui réunit deux très vieilles civilisations qui se respectent pour mieux se comprendre.
La paix du monde a besoin de l’amitié de la France et de la Chine.
jpr
大陆游客到金门 台湾神明改心意
上世纪40年代,中国内地有数百万人在共产党赢得内战后逃到了台湾。从那以后,在距大陆海岸线仅两英里远、但却由台湾当局管辖的小岛金门,当地的居民们一直把那些保卫台湾或者逃离大陆的反共人士奉为神明,以这种方式来应对他们的危险处境。
不过在反对大陆统治数十载后,金门的某些神仙也在改变着自己的心意。
至少他们的代言人是这样说的。李光前将军庙的主持表示,上世纪40年代在国共内战中身亡的国民党上校团长李光前现在希望能够平静地回到家乡。67岁的灵媒苏爱芝(音)说,一个被共军战士溺死、后来被奉为仙姑的女人甚至要求信徒们帮助她重新找到大陆的亲人。她还说,“仙姑附在我的身上,告诉我她想要回家。”
寺庙主持、灵媒和金门其他许多神仙的代言人正面对一个变换的时代。中国大陆和台湾的关系近几年大为缓和。尽管金门和附近的小金门岛上仍然散落着44座反共寺庙,但如今许多居民对于针对中国大陆这个巨邻发动军事或意识形态战争已经不那么感兴趣了。
幸运的是,中国的民间宗教──本土信仰和其它宗教元素的混合体,拥有大批信众──非常宽容。它不仅常常与其他信仰共存,信徒还可以创造、抛弃甚至对神明进行一番改造,这一点在那些不那么灵验的神明身上表现得尤为明显。
随着中国大陆和台湾关系的改善,金门的反共神仙们开始失去他们的灵气。研究反共教派的金门人类学家戚常卉说,“中国的民间宗教没有经文,因此每个人都有自己的一套解释方法。眼下的风气是,神仙们对中国大陆不再有那么深的敌意。”
神明们态度转变的另一个原因或许和经济