天天看點

SMB協商過程

近日閑來無事,由于前段機關網絡配置出現問題導緻邏輯環路,使網絡癱瘓,雖然後面重新配置後正常,但還是吸取了不少經驗,是以對網絡流量及資料分析産生興趣。我單獨模拟了一些簡單了網絡連接配接過程進行了抓包,但還是有很多疑問,下面是在網絡搜到的一篇關于cifs/smb的文章,感覺很不錯,分享過來,以備以後所需。

本文,我将向大家解釋什麼是cifs和smb,它們如何工作和這些協定裡一些共同的不安全隐患。

本文将會成為學習微軟網絡知識的一個有用資源。smb協定是一個在lan中非常通用的協定了。我為

大家提供了一個關于如何操作smb例子的源代碼。

你将會學習到在所有smb密碼都是加密的情況下,如何使用arp毒藥來獲得清晰的smb密碼(不需要

粗魯與暴力)。你将會了解smb與netbios之間的關系。你同樣會學到什麼是微軟遠端管理協定(rap),

以及如何使用它來掃描遠端smb伺服器上的共享資源。

本文提供的程式和資料都隻有一個教育性的目的。你将用它來做的任何事情與我無關。

--[ 2什麼是smb/cifs ?

依照微軟的意思,cifs是為客戶系統在網絡上向伺服器請求檔案和列印服務的開放跨平台的運作

機制。它是建立在廣泛應用于個人電腦和工作站等作業系統的标準伺服器消息塊(smb)協定。

實際上,smb是一個通過網絡在共享檔案,裝置,命名管道和郵槽之間操作資料的協定。cifs是

smb的一個公共版本。

smb用戶端的可用系統:

for microsoft :

windows 95, windows for workgroups 3.x, windows nt,2000 and xp

for linux :

smblient from samba, smbfs for linux

smb伺服器:

samba

microsoft windows for workgroups 3.x

microsoft windows 95

microsoft windows nt

the pathworks family of servers from digital

lan manager for os/2,sco,etc

visionfs from sco

totalnet advanced server from syntax

advanced serverfor unix from at&t (ncr?)

lan server for os/2 from ibm.

--[ 3 會話的建立

注意:smb協定已經被發展成為可以運作于dos作業系統,是以位元組順序将會和網絡順序相反。

smb可以運作在tcp/ip,netbeui,decnet和ipx/spx協定之上。如果smb執行于tcp/ip,decnet

或則是netbeui之上,那麼netbios名字必須被使用。

我将會在第六章向大家介紹什麼是netbios。但是現在,你必須知道netbios名字用來在網絡上鑒

别一台計算機。

smb技術的發展開始于八十年代,出現過很多版本的smb協定。但是最通用的(在windows 98,

windows nt,windows 2000 and xp)是nt lm 0.12版本。本文是基于nt lm 0.12版本之上的。

你必須知道一個smb域名是用來鑒别一個smb伺服器上的一組資源的(使用者,列印機,檔案……)。

那麼一個用戶端是如何與一個伺服器建立smb會話的呢?

讓我們假設一個這樣的環境:一個用戶端希望通路一台伺服器上的特定資源。

1 - 開始于用戶端向伺服器請求一個netbios會話。用戶端發送它的已編碼的netbios名字到smb

伺服器(它們在139端口監聽連接配接請求)。伺服器接收到netbios名字後回複一個netbios會話資料報給

有效的會話連接配接。用戶端在建立了連接配接之後才能進入通路。

2 - 用戶端發送一個smb negprot請求資料報(negprot是磋商協定“negotiate protocol”的

簡寫)。用戶端列出了它所支援的所有smb協定版本。

3 - 通過磋商之後,用戶端程序向伺服器發起一個使用者或共享的認證。(下一章中我們将會看到

共享認證和使用者認證之間的不同)。

這個過程是通過發送sesssetupx(sesssetupx是會話建立和x“session setup and x”的簡稱)

請求資料報實作的。用戶端發送一對登入名/密碼或一個簡單密碼到伺服器,然後伺服器通過發送一個

sesssetupx應答資料報來允許或拒絕本次連接配接。

4 - 好了,在用戶端完成了磋商和認證之後,它會發送一個tconx資料報并列出它想通路的特定

網絡資源的名稱,之後伺服器會發送一個tconx應答資料報以表示此次連接配接是否接受或拒絕。

netbios session request

(netbios name)

[client] ---------------------------> [server]

1)

netbios session granted

[client] <-------------------------- [server]

smb negprot request

2)

smb negprot reply

smb sesssetupx request

3)

smb sesssetupx reply

smb tconx request

4)

smb tconx reply

關于每個資料報的較長的描述在第六章裡有詳細的講解。

--[ 4 - smb的安全等級

在smb中有兩種安全模式:

第一種是“共享”級的安全模式。這種安全模式需要一個通路網絡上共享資源的密碼。使用者通過

這個正确的密碼來通路網絡資源(ipc,磁盤,列印機)。他可以是網絡上任何一個知道共享資源服務

器名字的使用者。

第二種是“使用者”級的安全模式。這是在第一種模式上的增強版。它堅持使用一對登入名/密碼來

通路共享資源。是以如果一個使用者想通路這種類型的共享資源,就必須同時提供登入名和密碼。這種

模式對了解使用者如何使用共享資源是很有幫助的。

--[ 5 - 密碼

在smb協定中,如果你想進行一次在伺服器上的請求認證,你的密碼可以以原碼或加密後的形式發

送到伺服器端。如果伺服器支援加密屬性,用戶端必須發送一個應答信号。在negprot應答資料報中,

伺服器會給用戶端發送一個密鑰。然後,用戶端将密碼加密并通過sesssetupx請求資料報發送到服務

器端。伺服器将會核查密碼的有效性,并由此允許或拒絕用戶端的通路。

你必須知道一個smb密碼(未加密)的最大長度是14位。密鑰的長度一般為8位,加密過後的密碼長

度為24位。在ansi密碼中,密碼中的所有位都轉換成大寫的形式然後再加密。

密碼是以dec編碼方式進行加密的。

--[ 6 - 幾種smb資料報的描述

這一部分,我将會對smb協定中涉及到的大多數重要的資料報類型進行分析。我知道這或許很煩,

不過這是了解smb的工作機制和進行攻擊的基礎。我将會解釋什麼是資料報中最重要的類型。每種命

令都對應兩種資料報類型,請求資料報和應答資料報。

----[ 6.1 - smb資料報的正常特征

通常情況下,smb運作于tcp/ip協定組之上。那麼我們就假設smb運作在tcp層之上。在tcp層上面,

你常常會發現netbios(nbt)頭部。在nbt上面,有smb基礎封包頭部。在smb基礎封包頭部之上,就是

另一種依賴于特定請求指令的頭部。

----------------------

│ tcp header │

│ netbios header │

│ smb base header │

│ smb command header │

│ data │

“smb base header”包含了幾種資訊,像接收緩沖區的長度,允許的最大連接配接數目……它也包

含了一個鑒别請求指令的數字。

“smb command header”包含了所有的請求指令的參數(像磋商協定版本指令……)。

“data”容納了請求指令的資料。

我們把“smb packet”看成:netbios header + smb base header + smb command header

+ data。

注意:我将使用這個定義:

typedef unsigned char uchar; // 8 unsigned bits

typedef unsigned short ushort; // 16 unsigned bits

typedef unsigned long ulong; // 32 unsigned bits

而string被定義為以空字元結束的ascii字元串。

----[ 6.2 - netbios與smb

netbios(network basic input and output system)在微軟的網絡系統中被廣泛使用。它是

一個軟體接口和命名系統。每台主機都有一個長度為15個字元的netbios名字,且第十六個字元用來

标志主機的類型(域名伺服器,工作站……)。

第十六個字元的選擇:

0x00 基礎電腦,工作站。

0x20 資源共享伺服器。

這還有一些其他的值可選,不過我們對這兩個最感興趣。第一個(0x00)鑒定一台工作站,第二個

(0x20)鑒定伺服器。

在一個smb資料報中,netbios頭部對應netbios會話頭部。

定義如下:

uchar type; // type of the packet

uchar flags; // flags

ushort length; // count of data bytes (netbios header not included)

“flags”域的值總是被置為0。

“type”域有幾種可能的選擇:

0x81 對應一個netbios會話請求。這個代碼在用戶端發送它的netbios名字到伺服器是使用。

0x82 對應一個netbios會話應答。這個代碼在伺服器向用戶端準許netbios會話時使用。

0x00 對應一個會話消息。這個代碼總是在smb會話中被使用。

“length”域包含了資料位元組的長度(netbios頭部沒有被包含在内)。資料包含在netbios頭部

以上的所有部分(它可能是 smb base header + smb command header + data 或 netbios名字)。

netbios名字與編碼。

netbios編碼名字的長度為32位元組。

netbios名字總是以大寫的形式存在的。

編碼一個netbios名字非常的簡單。例如我的計算機的netbios名字是“bill”,它是一個工作

站,是以它的第十六個字元為“0x00”。

首先,如果一個netbios名字比15位元組短,就會在右邊補填上空格。

“bill “

十六進制為: 0x42 0x49 0x4c 0x4c 0x20 0x20 ......0x00

每個位元組都分裂為4位一組:

0x4 0x2 0x4 0x9 0x4 0xc 0x4 0xc 0x2 0x0 .......

而且每個4位都要添加ascii碼‘a’的值(0x41)。

0x4 + 0x41 = 0x45 -> ascii value = e

0x2 + 0x41 = 0x43 -> ascii value = c

……

最後netbios名字被編碼為32位元組長。

注意:

smb可以直接運作于tcp之上而無須nbt(在windows 2k和xp上它們使用455端口)。此時,

netbios名字沒有被限制在15字元以内。

----[ 6.3 - smb的基礎封包頭部

這個頭部在所有的smb資料報中都會使用,以下是它的定義:

uchar protocol[4]; // contains 0xff,'smb'

uchar command; // command code

union {

struct {

uchar errorclass; // error class

uchar reserved; // reserved for future use

ushort error; // error code

} doserror;

ulong status; // 32-bit error code

} status;

ushort flags2; // more flags

ushort pad[6]; // ensure section is 12 bytes long

ushort pidhigh; // high part of pid

ulong unused; // not used

ulong unused2;

} extra;

};

ushort tid; // tree identifier

ushort pid; // caller's process id

ushort uid; // unauthenticated user id

ushort mid; // multiplex id

uchar wordcount; // count of parameter words

ushort parameterwords[ wordcount ]; // the parameter words

ushort bytecount; // count of bytes

uchar buffer[ bytecount ]; // the bytes

“protocol”域包含協定(smb)的名字,前面放了一個0xff。

“command”域包含請求指令的資料。例如0x72就是“磋商協定”指令。

“tid”域在用戶端成功和一台smb伺服器上的資源建立連接配接後被使用的。tid數字用來鑒别資源。

“pid”域在用戶端成功在伺服器上建立一個程序是使用。pid數字用來鑒别程序。

“uid”域在一個使用者被成功通過驗證後被使用。uid數字用來鑒别使用者。

“mid”域在用戶端擁有幾個請求(程序,線程,檔案通路……)是和pid同時使用。

“flags”域也很重要,如果第15位置1,則使用unicode編碼。

----[ 6.4 - 重要smb指令的描述

smb 磋商協定(negprot)

磋商協定在smb會話建立連接配接的第一步時使用。

在smb基礎封包頭部中的“command”域被填充為:0x72。

下面是negprot請求與應答資料報的定義:

request header

uchar wordcount; //count of parameter words = 0

ushort bytecount; //count of data bytes

uchar bufferformat; //0x02 -- dialect

uchar dialectname[]; //ascii null-terminated string

} dialects[];

這個資料報包括用戶端向伺服器發送的它所支援smb協定的所有版本資訊。

有三件事要說,在這個封包中:

“wordcount”域總是被置為零;

“bytecount”域等于結構“dialects”的長度;

“bufferformat”域總是等于0x02。

“dialectname”包含smb協定支援的幾種版本資訊。

應答資料報頭部:

uchar wordcount; count of parameter words = 17

ushort dialectindex; index of selected dialect

uchar securitymode; security mode:

bit 0: 0 = share, 1 = user

bit 1: 1 = encrypt passwords

ushort maxmpxcount; max pending multiplexed requests

ushort maxnumbervcs; max vcs between client and server

ulong maxbuffersize; max transmit buffer size

ulong maxrawsize; maximum raw buffer size

ulong sessionkey; unique token identifying this session

ulong capabilities; server capabilities

ulong systemtimelow; system (utc) time of the server (low).

ulong systemtimehigh; system (utc) time of the server (high).

ushort servertimezone; time zone of server (min from utc)

uchar encryptionkeylength; length of encryption key.

ushort bytecount; count of data bytes

uchar encryptionkey[]; the challenge encryption key

uchar oemdomainname[]; the name of the domain (in oem chars)

這個資料報由伺服器發出,它包含smb協定支援的版本清單,伺服器的smb域名,如果需要還要

包含密鑰。

重要的:

第一個感興趣的域是“securitymode”位。如果第0位被選中,那麼我們就選擇了使用者安全模式;

如果沒有,則擁有共享安全模式。如果第1位被選中,密碼就使用dec加密算法進行編碼。

“sessionkey”域被用來鑒别會話。一個會話有單一的一個會話鑰匙。

“capabilities”域表明伺服器是否支援unicode字元串,或nt lm 0.12特别的指令……

資料被放在封包頭部的結束處。通過一個negprot應答,這些資料與“encryptionkey”和

“oemdomainname”相對應。

“oemdomainname”域的長度等于(bytecount - encryptoinkeylength)。

“oemdomainname”字元串包含伺服器的smb域名。

sesssetupx(session setup and x)

sesssetupx資料報被用來處理使用者鑒别,或在你通路資源時提供一個密碼。

sesssetupx的指令代碼是:0x73。

請求資料報頭部:

uchar wordcount; count of parameter words = 13

uchar andxcommand; secondary (x) command; 0xff = none

uchar andxreserved; reserved (must be 0)

ushort andxoffset; offset to next command wordcount

ushort maxbuffersize; client's maximum buffer size

ushort maxmpxcount; actual maximum multiplexed pending requests

ushort vcnumber; 0=first (only),nonzero=additional vc number

ulong sessionkey; session key (valid iff vcnumber != 0)

ushort caseinsensitivepasswordlength; account password size, ansi

ushort casesensitivepasswordlength; account password size, unicode

ulong reserved; must be 0

ulong capabilities; client capabilities

ushort bytecount; count of data bytes; min = 0

uchar caseinsensitivepassword[]; account password, ansi

uchar casesensitivepassword[]; account password, unicode

string accountname[]; account name, unicode

string primarydomain[]; client's primary domain, unicode

string nativeos[]; client's native operating system, unicode

string nativelanman[]; client's native lan manager type, unicode

這個封包提供很多關于用戶端系統的資訊。

“maxbuffersize”域非常的重要,它提供用戶端可以接收資料報的最大長度。如果你将這個域

設定為零,那麼你不會接收到任何類型的資料。

這個資料報内,有幾個字元串。最總要的是“casesensitivepassword”(unicode編碼的密碼)

域和“caseinsensitivepassword”(ansi編碼的密碼)域。

這兩個域中的一個被使用,它取決于伺服器是否支援unicode編碼(在磋商協定應答封包中描述)。

密碼的長度儲存在“caseinsesitivepasswordlength”或“casesensitivepasswordlength”裡。

其他字元串,請參見它後面的描述。資料的長度儲存在“bytecount”域中。

uchar wordcount; count of parameter words = 3

ushort action; request mode: bit0 = logged in as guest

string nativeos[]; server's native operating system

string nativelanman[]; server's native lan manager type

string primarydomain[]; server's primary domain

在這個資料封包裡也包含了很多資訊:作業系統類型,smb伺服器版本資訊和伺服器的域名。

如果連接配接失敗,那麼在 nativeos, nativelanman

and primarydomain 裡面将沒有任何東西。

我們已經講完了“硬體”部分,下面我們來看看smb協定。

----[ 6.5 我們如何才能将本應該加密的smb密碼清楚的還原 ?

在會話的建立過程中,密碼是在sesssetupx階段被發送到伺服器的。而smb negprot應答封包包

含了一個“securitymode”域,它判斷是否允許使用加密屬性。

如果你想在所有的密碼都被加密後獲得一個清晰的密碼,你可能會面對兩種情況。

第一種情況是得到密鑰和加密過的密碼,然後暴力破解。它會花費你很多的時間……

一些程式如 lophtcrack (附smbgrinder),dsniff or readsmb2 會嗅探到smb加密過的密碼。

第二種方法是劫持連接配接,并使用戶端确信密碼不用加密後傳送。

這種技術解釋起來有點複雜,不過我會告訴你如何才能實作 !

如果伺服器配置成需要加密的密碼,那麼smb negprot應答資料報就會選種“securitymode”的

第1位。但是,如果攻擊者在伺服器之前發送了一個negprot應答資料報,且相應的第一位被置為零就

可以了,這樣密碼就會以明文的形式出現在sesssetupx請求封包。

negprot request

[client] ----------------------------------> [server]

[ attacker ]

(攻擊者等待一個negprot請求資料報)

[client] <-------------│ [server]

│ fake negprot reply

(攻擊者發送一個虛假的neprot應答資料報)

real negprot reply

[client] <---------------------------------- [server]

[attacker (什麼都不做)]

sessetupx request with the password in clear text

(攻擊者嗅探到明文形式的密碼)

以上的圖表明了在網絡上進行一次直接資料報注射過程。大多數情況下,這種方法并不會發生,

因為虛假的negprot應答資料報會被處理。還有一個問題就是會話特性,有效的密碼它不會在交換環

境中工作……

我們可以使用arp毒藥(arp-poisoning)來避免上面的所有問題。

我不會解釋或描述什麼是arp毒藥,你可以在互連網上找到很多這方面的文章。但是如果你不知道

這是什麼,你隻須知道這種攻擊允許攻擊者在用戶端和伺服器之間進行重定向并修改網絡通信。

如果你考慮到這種情形,攻擊者就在他們之間。

這就是man in the middle……

----[ 6.6 - man in the middle 攻擊

“attack where your enemy is not expecting you“

sun tzu, 《 the art of war 》

現在我就要為大家描述什麼是 man in the middle 攻擊。這種攻擊允許你回避交換機,可以避

免連接配接失敗,進而獲得密碼的明文表達式。

現在我們認為用戶端和伺服器之間的通信被攻擊者重定向了(由于arp毒藥)。用戶端向伺服器請

求一個smb會話,它會向伺服器的139端口發送一個資料報。這時攻擊者接收到了這個資料報,但是攻

擊者并沒有将這個資料報重新發送到伺服器。

所有接收到的發送給伺服器smb端口的資料報(現在發送到了攻擊者的主機了)被重新定向到攻擊者

主機的本地端口1139(使用nat或iptables非常容易實作)。在攻擊者的本地端口1139,有一個程式(一

個透明的代理程式)進行修改并重定向smb資料報。

iptables/nat的指令如下:

将接收到的資料報(139端口)重定向到本地端口(例如1139)。

#iptables -t nat -a prerouting -i eth0 -p tcp -s 192.168.1.3 --dport 139 -j redirect --to-port 1139

192.168.1.3是用戶端的ip位址。

重定向所有的網絡通信:

#iptables -t nat -a postrouting -o eth0 -j masquerade

需要做哪些修改呢?

攻擊者修改negprot應答資料報使密碼以明文的形式傳送,攻擊者同樣要修複密鑰。他将密鑰的長

度設定為零,并将域名代替密鑰。攻擊者将“securitymode”位設定為零。這樣,密碼就不會被加密了。

此後,用戶端将會在sesssetupx請求資料報中把密碼以明文的的方式傳送。在攻擊者獲得了密碼

後,他會在把sesssetupx請求資料報發送給伺服器之前用密鑰将密碼加密。

伺服器發送一個sesssetupx應答封包以接受或拒絕會話。攻擊者重定向sesssetupx應答封包和

以後的所有網絡通信。

會話連接配接不會失敗,而且沒有人知道我們的 man in the middle !

描述:

arp-p arp-p

[client] <--------- [attacker] ---------> [server]

攻擊者使用arp毒藥攻擊,進而在兩台主機之間重定性所有的網絡資料報。

[client] <---------> [attacker] <---------> [server]

網絡傳輸的重定向依靠nat或iptables來實作。

port 139

[client] -----------------> [attacker] [server]

攻擊者接收到第一個發送給smb伺服器的資料報。

[client] ----------------->[attacker 139] [server]

v

[attacker 1139]

攻擊者将它重定向到1139端口。在1139端口上,我們的代理程式正在監聽。

攻擊者接收到了negprot請求資料報。

[client] [attacker] -------------------> [server]

攻擊者重定向negprot請求資料報到伺服器。

negprot reply

[client] [attacker] <---------------------------- [server]

(加密屬性位設定為要求對密碼進行加密)

伺服器發送了一個将加密屬性設定為1的negprot應答資料報,要求用戶端對密碼進行加密傳送。

攻擊者并不會重定向發送這個資料報。他改變了要求加密的那一位,而告訴用戶端不用對密碼進行加

密。

[client] <----------------------------- [attacker] [server]

(加密屬性位被設定為無須加密密碼 )

攻擊者将修改過的無須加密密碼的negprot應答封包發送到用戶端。

sesssetupx request

[client] ------------------------> [attacker] [server]

(密碼以明文形式傳送)

用戶端将密碼以明文形式傳送,這是攻擊者得到了伺服器的密碼了 !

[client] [attacker] ---------------------> [server]

(密碼被加密過後傳送)

攻擊者将密碼加密後通過sesssetupx請求資料報發送到伺服器。

sesssetupx reply

[client] <------------- [attacker] <---------------- [server]

伺服器發送sesssetupx應答封包,攻擊者隻是将它重定向到用戶端。

[client] <------------> [attacker] <--------------> [server]

攻擊者繼續在伺服器與用戶端之間重定向資料報,直到smb會話結束。

----[ 6.7 - 注意windows 2k/xp裡基于tcp的smb操作

就想我先前說的,在windows 2k/xp中smb可以直接運作于tcp之上。smb伺服器在445端口上監聽

所有的連接配接。但是這并不是如此的“直接”,實際上,我們使用一個4位元組長的資料代替了netbios頭部。

│---------------│

│ tcp │

│special header │

│ smb base hdr │

特殊頭部的定義如下:

uchar zero; // set to zero

uchar length[3]; // count of data bytes

// the 4 bytes of the header are not included

這個特别的頭部和netbios頭部并沒有太大的差別,下面你就會知道為什麼了。

下面是netbios頭部:

在smb運作于tcp之上時,netbios請求會話就不再需要了。

實際上,用戶端和伺服器的netbios名字并不需要發送。是以,在netbios裡的“type”域總是等

于零(如果“type”域不等于零,在用戶端發送它的netbios的編碼後的名字時這個域被置為0x81,如

果是伺服器就填入0x82)。記住,在smb的會話期間,“type”域始終等于零。

第一個位元組完全相同。

最後三個位元組:

netbios頭部的“flags”域始終置為零。隻有資料報的長度會占據最後的兩個位元組。

我們可以得出這個結論:在netbios沒有使用時,netbios頭部和特殊頭部沒有什麼差別。

downgrade 攻擊:

如果用戶端(運作于windows 2k 或 xp之上)使用了nbt,它在連接配接時總是同時使用139和445端口。

如果用戶端在445端口接收到一個應答封包,用戶端就會在139端口發送一個rst資料報。如果用戶端在

445端口沒有接收到應答封包,他會試圖使用139端口進行連接配接。如果在兩個端口都沒有回應,那麼這

次會話就算失敗了。

如果用戶端沒有使用nbt,它僅在445端口上進行連接配接。為了完成 downgrade 攻擊,強迫用戶端

不使用445端口而使用139端口,你必須是用戶端确信445端口是關閉的。在使用透明代理攻擊的情況下

是非常容易實作的。在使用iptables的情況下,隻須在攻擊者的主機上将接收的所有網絡資料報從445

端口重定向到其他的端口。這樣用戶端就會使用139端口了。

以上假設是基于用戶端使用了nbt的。

如果用戶端沒有使用,那麼透明代理就會在445端口上進行資料報的流通。

好的,我們已經完成了還原密碼的攻擊了。現在我們要學習smb的另一個重要部分。

--[ 7 - 事物處理子協定與rap指令

在這部分我會解釋一些smb的指令:rap指令。這些指令使用事物處理子協定。我同樣會描述這些

子協定。

----[ 7.1 事物處理子協定

在大量的資料通過smb會話傳送時,或則有一個特别的操作請求,那麼smb協定就會包含一個事物

處理子協定。

事物處理子協定主要用在smb遠端過程調用(rpc):rap指令(rap是remote administration

protocal),我将會在稍後解釋。

事物處理子協定并不是來源與smb協定。它隻是為smb提供的另外一個指令。是以事物處理子協定

是基于smb基礎封包頭部的,它的指令代碼是0x25。

像其他指令一樣有發送和請求封包。

以下是事物處理請求封包頭部:

uchar wordcount; count of parameter words; value =

(14 + value of the “setupcount“ field)

ushort totalparametercount; total parameter bytes being sent

ushort totaldatacount; total data bytes being sent

ushort maxparametercount; max parameter bytes to return

ushort maxdatacount; max data bytes to return

uchar maxsetupcount; max setup words to return

uchar reserved;

ushort flags; additional information:

bit 0 - also disconnect tid in tid

bit 1 - one-way transaction (no response)

ulong timeout;

ushort reserved2;

ushort parametercount; parameter bytes sent this buffer

ushort parameteroffset; offset (from header start) to parameters

ushort datacount; data bytes sent this buffer

ushort dataoffset; offset (from header start) to data

uchar setupcount; count of setup words

uchar reserved3; reserved (pad above to word)

ushort setup[setupcount]; setup words (# = setupwordcount)

string name[]; name of transaction

(null if smb_com_transaction2)

uchar pad[]; pad to short or long

uchar parameters uchar pad1[]; pad to short or long

uchar data[ datacount ]; data bytes (# = datacount)

在大多數情況下,一個rap指令通過事物處理子協定來發送時都需要幾個事物處理資料報來發送參

數和資料。參數位元組通常首先發送,資料位元組緊跟在後。如果幾個事物處理資料報必須相關聯時,服

務器會送下面的這個小的資料報:

中間應答封包 :

uchar wordcount; count of parameter words = 0

ushort bytecount; count of data bytes = 0

在事物處理請求封包頭部,“totalparametercount”域描述發送的參數位元組的長度,在

“totaldatacount”域中也是這樣的(發送的資料數目)。

從smb基礎封包頭部的開始到參數字元的偏移量儲存在“parameteroffset”裡,而資料字元的

偏移量儲存在“dataoffset”域裡。

“parameter”域包含參數字元,而“data”域則包含資料字元。

在“datacount”域和“parametercount”域裡分别儲存了事物處理資料報裡的資料位元組和參數

位元組的長度。

注意一下“wordcount”域,它包含了下面的值:14 + “setupcount”域的值。但通常情況下,

“setupcount”域都等于零。

發送的請求資料報和應答資料報之間并沒有太多的差别。

事物處理應答封包:

uchar wordcount; count of data bytes; value = 10 +

“setupcount“ field.

ushort reserved;

ushort parameterdisplacement; displacement of these parameter bytes

ushort datadisplacement; displacement of these data bytes

uchar reserved2; reserved (pad above to word)

ushort setup[setupwordcount]; setup words (# = setupwordcount)

uchar data[datacount]; data bytes (# = datacount)

用戶端必須使用“parameteroffset”和“dataoffset”以了解參數和資料位元組的偏移量(從smb

基礎封包頭部開始)。

----[ 7.2 - rap指令

rap(remote administation protocal)是smb的rpc實作。

rap 請求封包 :

│---------------------------│

│tcp hdr │

│netbios hdr │

│smb base hdr │

│smb transaction request hdr│

│rap request parameters │

│rap request datas │

rap 應答封包 :

│smb transaction reply hdr │

│rap reply parameters │

│rap reply datas │

在你使用rap指令時,你總會在事物處理(請求和應答)的“name”域中找到“/pipe/lanman”

字元串。

這有幾個rap指令的例子:

- netshareenum : 獲得伺服器上所有共享資源的資訊;

- netserverenum2 : 列舉特定域裡所有計算機的特定類型;

- netservergetinfo : 獲得指定伺服器的資訊;

- netsharegetinfo : 獲得特定共享資源的資訊;

- netwkstauserlogon : 在smb伺服器上進行一次登入;

- netwstauserlogoff : 登出;

- netusergetinfo : 獲得指定使用者的資訊;

- netwkstagetinfo : 獲得指定工作站的資訊;

- samoemchangepassword : 更改遠端smb伺服器上一個使用者的密碼。

我不會列舉所有的指令,而隻是舉一個例子。

--[ 8 - 使用rap指令列出伺服器上所有可得的共享清單

這部分是上面的補充。我将會示範一個如何使用rap指令的例子。

我們如何才能獲得網絡上的每人都可通路的smb共享資源:

其實過程很簡單。用戶端必須在伺服器上通過認證。這些在第三章裡都有講解。在伺服器通過驗

證後,用戶端發送一個tconx請求資料報給伺服器(在接收到sesssetupx應答資料報之後)。

tconx 的意思是 tree connect and x。

tconx請求資料報用來通路一個共享資源。

----[ 8.1 - tconx資料報

tconx資料報是建立在smb基礎封包頭部之上的,指令代碼為0x75。

uchar wordcount; count of parameter words = 4

ushort flags; additional information

ushort passwordlength; length of password[]

ushort bytecount; count of data bytes; min = 3

uchar password[]; password

string path[]; server name and share name

string service[]; service name

密碼在會話建立過程中被發送到了伺服器。如果密碼的長度為1,則密碼就被置為空(0x00)。

“path”域包含了你想要通路的共享資源的名字。它使用unicode編碼。如過我想通路一台

“myserver”伺服器上的“myshare”資源,“path”字元串就該置為“//myserver/myshare”。

“service”包含了請求資源的類型:

stringtype of ressource

“a:” 磁盤共享.

“lpt1:” 列印機.

“ipc” 命名管道.

“comm” 通信裝置.

“?????” 任何裝置類型.

如果你要掃描裝置的類型,你必須在“service”域裡使用“?????”。

在你發送了一個tconx請求資料報到伺服器後,它會給你發送一個tconx的應答封包。你還必須

修複“tid”域(在smb基礎封包頭部),因為它是rap指令裡的事物處理請求。你還要告訴伺服器你想

獲得那些你有權得到的資源名字。當然,你可以通過“netshareenum”指令來獲得它們。

----[ 8.2 - rap指令“netshareenum”的解釋

我們将要學習rap指令裡的“netshareenum”。

rap指令中的“netshareenum”請求:

函數netshareenum的16位代碼: 0;

參數描述符: “wrlen”;

傳回的資料描述符: “b13bwz”;

一個16位的值為0x01的整數;

一個16位整數包含的獲得資料的緩沖區長度;

在這個請求資料報中不需要任何資料,是以“datacount”域和“totaldatacount”域都置零。

│--------------------------------------------│

│ netbios hdr │---------> 4 bytes

│ smb base hdr │---------> 32 bytes

│ smb transaction request hdr │

事物處理請求的“parameters”域獲得rap請求指令的參數:

│--------------│

│ 0x0000 │ ----------------------------------------> a

│--------------│--------------│--------------│

│ w r │ l e │ h 0x00│-----------> b

│--------------│--------------│--------------│-------│

│ b 1 │ 3 b │ w z │ 0x00 │---> c

│ 0x0001 │ 0xffff │--------------------------> d

│--------------│--------------│

a: netshareenum函數代碼: 0x00

b: 參數描述符

c: 資料描述符

d: 0x01(已定義值)和0xffff(擷取資料報的最大長度)

伺服器的應答:

“parameters”域接收到事物處理應答封包頭部資訊:

一個16位整數包含了傳回的狀态值:

成功 0

拒絕通路 5

拒絕通路網絡 65

更多資料 234

伺服器已關閉 2114

事物處理配置錯誤 2141

一個16位的“轉換字”,用來計算備注資訊的偏移量。

一個16位獲得傳回的條目數 = 傳回share_info資料結構的數目。

一個16位獲得可利用的條目數。

在事物處理應答封包的“data”域中包含了幾組share_info的資料結構。

share_info資料結構包含了可利用資源的資訊,定義如下:

struct share_info {

char shi1_netname[13]; /*name of the ressource*/

char shi1_pad; /*pad to a word*/

unsigned short shi1_type; /*code specifies the type of the shared resssource :

0 disk directory tree

1 printer queue

2 communications device

3 ipc*/

char *shi1_remark; /*remark on the specified ressource*/

}

shi1_remark是一個32位的字元傳指針。它包含了相應資源的備注資訊。你必須取出它的後16位

到“converter word”域中,以知道這個備注字元串和rap應答封包參數頭部之間的偏移量。

實際上以ascii編碼是:

│ netbios hdr │------------> 4 bytes

│ smb base hdr │------------> 32 bytes

│ smb trans reply hdr │

事物處理應答頭部的“parameters”域定義:

(對應于netshareenum函數傳回的參數)

│ status code │-------------> 2 bytes

│ converted word │-------------> 2 bytes

│ number of entries returned │-------------> 2 bytes

│ number of entries available │-------------> 2 bytes

事物處理應答封包的資料部分:

(對應于多個share_info資料結構)

│ shi1_netname │-----------> 13 bytes

│ shi1_pad to pad to word │-----------> 1 byte

│ type of service │-----------> 2 bytes

│ pointer to remark string │-----------> 4 bytes

.

其他的share_info資料結構

│ remark string 1 │

│ another remarks strings │

--[ 9 - 結論

我希望你能在這篇文章中學到些東西。如果你有任何意見,問題,請與我聯系:

--[ 10 - 參考

[1] "a common internet file system (cifs/1.0) protocol

preliminary draft", paul j.leach and dilip c. naik

http://www.snia.org/tech_activities/cifs/cifs-tr-1p00_final.pdf

[2] "cifs remote administration protocol preliminary draft"

paul j.leach and dilip c. naik

http://us6.samba.org/samba/ftp/specs/cifsrap2.txt

[3] rfc 1001

http://www.faqs.org/rfcs/rfc1001.html

[4] rfc 1002

http://www.faqs.org/rfcs/rfc1002.html

繼續閱讀