修改Windows SMB相關服務的預設連接埠
轉自:http://www.xfocus.net
建立時間:2004-08-05
文章屬性:原創
文章提交:tombkeeper (t0mbkeeper_at_hotmail.com)
修改Windows SMB相關服務的預設連接埠
作 者:於暘
郵 件:tombkeeper[0x40]nsfocus[0x2e]com
tombkeeper[0x40]xfocus[0x2e]org
完成於:2004.07.22
關鍵字:SMB、NetBT、NetBios、netbt.sys、預設連接埠
Windows NT系列作業系統的NetBT(NetBios Over Tcpip)服務,是用來處理SMB
(Server Message Block)相關的服務/客戶操作的。
NetBT服務對應的驅動程式檔案是netbt.sys,對應的登錄機碼是:
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/NetBT。
微軟的KB 120642和KB 314053分別描述了Windows NT、Windows 2000、Windows XP上
該索引值的部分選擇性參數。
NetBT服務對應的在Windows NT 4.0上對應的連接埠是:
NameservicePort 137/UDP
DatagramPort 138/UDP
SessionPort 139/TCP
從Windows 2000開始,微軟引入了SMB Direct Over TCP的445連接埠。上述的137、
138、139 連接埠雖然被保留,並可正常工作,但是預設情況下,系統總是會使用445端
口進行SMB會話,僅在445連接埠工作失敗的情形下,才會使用139連接埠作為SessionPort。
445連接埠預設情況下是始終開放的。如果要關閉該連接埠,可以參考微軟KB 301673中的
方法,在
HKEY_LOCAL_MACHINE/System/CurrentControlSet/Services/NetBT/Parameters
中增加一個值:
Value Name: SmbDeviceEnabled
Type: REG_DWORD
Value Data: 0
然後重新啟動系統。
順便提一下,如果要關閉139連接埠,可以參考微軟的KB 299977:
1、 單擊開始,指向設定,然後單擊網路和撥號連線。
2、 單擊您希望靜態配置的本地串連,單擊檔案菜單中的屬性。
3、 單擊 網際網路通訊協定 (IP) (TCP/IP),單擊屬性,單擊進階,然後單擊 WINS 選項卡。
4、 單擊禁用 NetBIOS over TCP/IP。
5、 單擊確定,單擊確定,再次單擊確定。
修改會立即生效,不必重新啟動系統。
這個445 連接埠可不可以改成別的值呢?分析netbt.sys可知,服務初始化的時候,
函數NbtReadRegistry分別調用ReadParameters和ReadSmbDeviceInfo從註冊表中擷取
NetBT服務的配置資訊:
; ------------------------------------------------------------------------
push [ebp+Handle]
push offset _NbtConfig
call _ReadParameters@8 ; ReadParameters(x,x)
push [ebp+KeyHandle]
call _ReadSmbDeviceInfo@4 ; ReadSmbDeviceInfo(x)
; ------------------------------------------------------------------------
ReadParameters讀取的註冊表值就在上面提到的三篇KB中基本都有相關說明,但
是ReadSmbDeviceInfo 所擷取的資訊,似乎還沒有現成的文檔描述。下面是逆向工程
出來的5.0.2195.6783版本netbt.sys的ReadSmbDeviceInfo函數:
; ------------------------------------------------------------------------
; __stdcall ReadSmbDeviceInfo(KeyHandle)
KeyHandle = dword ptr 8
push ebp
mov ebp, esp
lea eax, [ebp+KeyHandle]
push esi
push eax ; KeyHandle
push offset aParametersSmb ; "Parameters/Smb"
push [ebp+KeyHandle] ; int
call _NbtOpenRegistry@12 ; NbtOpenRegistry(x,x,x)
mov esi, eax
test esi, esi
jl short SetDefaultPort ;如果鍵不存在則轉向去設定預設值
push 1
push 1BDh ; 預設值445
push offset aSessionport ; "SessionPort"
push [ebp+KeyHandle]
call _NbtReadSingleParameter@16 ; NbtReadSingleParameter(x,x,x,x)
push 1
push 1BDh ; 預設值445
push offset aDatagramport ; "DatagramPort"
mov word_2BA88, ax
push [ebp+KeyHandle]
call _NbtReadSingleParameter@16 ; NbtReadSingleParameter(x,x,x,x)
push [ebp+KeyHandle] ; Handle
mov word_2BA8A, ax
call ds:__imp__ZwClose@4 ; __declspec(dllimport) ZwClose(x)
jmp short Return
SetDefaultPort:
mov SessionPort, 1BDh ;設定SessionPort為445
mov DatagramPort, 1BDh ;設定DatagramPort為445
Return:
mov eax, esi
pop esi
pop ebp
retn 4
; ------------------------------------------------------------------------
顯然,ReadSmbDeviceInfo會先試圖開啟
HKEY_LOCAL_MACHINE/System/CurrentControlSet/Services/NetBT/Parameters/Smb
然後分別讀取SessionPort 和DatagramPort,根據其中的值來設定相關連接埠。如果打
開鍵失敗,則轉向 SetDefaultPort,將兩個連接埠設定為預設的445,如果讀取值失敗,
NbtReadSingleParameter的第三型參也指定了預設的傳回值445。
SessionPort 和DatagramPort分別對應TCP和UDP的連接埠。不過我從來沒有見到過
UDP的SMB會話,所以,還是SessionPort更加重要一些。
然後NbtCreateAddressObjects根據這些資訊,來開啟連接埠,建立服務:
; ------------------------------------------------------------------------
mov eax, [ebp+var_8]
mov cx, SessionPort ; tcp連接埠值
mov esi, offset aSmbserver ; "*SMBSERVER "
mov [eax+1F2h], cx
mov eax, [ebp+var_8]
mov cx, DatagramPort ; udp連接埠值
mov [eax+1F6h], cx
mov eax, [ebp+var_8]
mov [eax+1F4h], di
mov eax, [ebp+var_8]
lea edi, [eax+1F8h]
movsd
movsd
movsd
movsd
push [ebp+var_8]
push 0
push 7F000001h
call _NbtCreateAddressObjects@12 ; NbtCreateAddressObjects(x,x,x)
; ------------------------------------------------------------------------
明確了流程,方法也就出來了。
HKEY_LOCAL_MACHINE/System/CurrentControlSet/Services/NetBT/Parameters/Smb
這個項預設情況下是沒有的,所以程式總是會轉向SetDefaultPort,如果我們手工創
建Smb 項和下面的兩個值,系統就會按照我們建立的值來設定連接埠。這是最簡單的辦
法。當然,如果你願意,手工修改netbt.sys 也是可以的。下面是一個把連接埠設定為
555的註冊表例子:
; ------------------------------------------------------------------------
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/NetBT/Parameters/Smb]
"SessionPort"=dword:0000022b
"DatagramPort"=dword:0000022b
; ------------------------------------------------------------------------
上面提到的修改,會同時影響伺服器和用戶端。也就是說,如果我們把連接埠改為
555,那麼不但原生SMB Direct Over TCP會監聽555連接埠,訪問其他機器的SMB服務
時也會嘗試往555 連接埠串連。也就是說,假使我們將兩台電腦做同樣的修改,那麼
這兩台電腦之間可以正常互訪共用,但是其它電腦則不能訪問它們。
修改這個連接埠有什麼用處呢?
1、 研究中有時候需要使用原生445連接埠,例如做一些SMB工作階段劫持的實驗。
2、 如果希望通過阻塞了445、139等連接埠的防火牆來訪問網際網路共用,可以將伺服器和
用戶端的SessionPort都設為80,這樣,兩者之間就會通過80連接埠進行SMB會話。
而且,一般來說,這種修改並不會影響對其他正常伺服器的訪問,因為對80建立
串連失敗後,用戶端會自動轉用139連接埠。
3、 如果我們按照一開始提到的方法,禁用139 連接埠,並且將一個網路內所有的系統
都修改為一個共同的值,那麼這些機器相互之間的共用訪問仍然不受任何影響,
但是任何外來的訪問都會失敗。這在某種程度上可以增強安全性,抵禦惡意入侵
和一些蠕蟲。
139 連接埠可不可以改為其它的呢?也是可以的,不過,沒有像上面那樣優雅的方
法,只能靠修改netbt.sys檔案或者動態修改記憶體中相應的位置。5.0.2195.6783版本
netbt.sys設定連接埠部分的代碼如下:
; ------------------------------------------------------------------------
66 C7 86 F2 01 00 00 8B 00 mov word ptr [esi+1F2h], 8Bh ; 139
66 C7 86 F4 01 00 00 89 00 mov word ptr [esi+1F4h], 89h ; 137
66 C7 86 F6 01 00 00 8A 00 mov word ptr [esi+1F6h], 8Ah ; 138
; ------------------------------------------------------------------------
Windows XP和Windows 2003上的相關結構和Windows 2000不同,代碼有些差別,
下面是5.2.3790.69版本netbt.sys設定連接埠部分的代碼:
; ------------------------------------------------------------------------
66 C7 86 F8 01 00 00 8B 00 mov word ptr [esi+1F8h], 8Bh ; 139
66 C7 86 FA 01 00 00 89 00 mov word ptr [esi+1FAh], 89h ; 137
66 C7 86 FC 01 00 00 8A 00 mov word ptr [esi+1FCh], 8Ah ; 138
; ------------------------------------------------------------------------
顯然,Opcode之間的差別也就是位移量,所以很容易寫出可以支援Windows 2000、
Windows XP和Windows 2003的動態或者靜態Patch代碼。
參考:
Windows 2000 或 Windows NT 的 TCP/IP 和 NBT 配置參數:
http://support.microsoft.com/default.aspx?kbid=120642
Windows XP 的 TCP/IP 和 NBT 配置參數:
http://support.microsoft.com/default.aspx?kbid=314053
You Cannot Make More Than One Client Connection Over a NAT Device
http://support.microsoft.com/default.aspx?kbid=301673