作者:Mr.Right、K0r4dji 申明:文中提到的攻擊方式僅為曝光、打擊惡意網絡攻擊行為,切勿模仿,否則后果自負。
“知己知彼,百戰不殆。”掃描探測,目的就是“知彼”,為了提高攻擊命中率和效率,基本上常見的攻擊行為都會用到掃描探測。
掃描探測的種類和工具太多了,攻擊者可以選擇現有工具或自行開發工具進行掃描,也可以根據攻擊需求采用不同的掃描方式。本文僅對Nmap常見的幾種掃描探測方式進行分析。如:地址掃描探測、端口掃描探測、操作系統掃描探測、漏洞掃描探測(不包括Web漏洞,后面會有單獨文章介紹Web漏洞掃描分析)。
地址掃描探測是指利用ARP、ICMP請求目標網段,如果目標網段沒有過濾規則,則可以通過回應消息獲取目標網段中存活機器的IP地址和MAC地址,進而掌握拓撲結構。
如:192.1.14.235向指定網段發起ARP請求,如果IP不存在,則無回應。

如果IP存在,該IP會通過ARP回應攻擊IP,發送自己的MAC地址與對應的IP。

ARP欺騙適用范圍多限于內網,通過互聯網進行地址掃描一般基于Ping請求。
如:192.1.14.235向指定網段發起Ping請求,如果IP存在,則返回Ping reply。


端口掃描是掃描行為中用得最多的,它能快速獲取目的機器開啟端口和服務的情況。常見的端口掃描類型有全連接掃描、半連接掃描、秘密掃描和UDP掃描。
全連接掃描調用操作系統提供的connect()函數,通過完整的三次TCP連接來嘗試目標端口是否開啟。全連接掃描是一次完整的TCP連接。
1)如果目標端口開啟 攻擊方:首先發起SYN包;
目標:返回SYN ACK;
攻擊方:發起ACK;
攻擊方:發起RST ACK結束會話。
2)如果端口未開啟 攻擊方:發起SYN包;
目標:返回RST ACK結束會話。
如:192.1.14.235對172.16.33.162進行全連接端口掃描,首先發起Ping消息確認主機是否存在,然后對端口進行掃描。

下圖為掃描到TCP3389端口開啟的情況。

下圖為掃描到TCP1723端口未開啟的情況。

半連接掃描不使用完整的TCP連接。攻擊方發起SYN請求包;如果端口開啟,目標主機回應SYN ACK包,攻擊方再發送RST包。如果端口未開啟,目標主機直接返回RST包結束會話。
如:192.1.14.235對172.16.33.162進行半連接端口掃描,首先發起Ping消息確認主機是否存在,然后對端口進行掃描。

掃描到TCP80端口開啟。

TCP23端口未開啟。

TCP FIN掃描是指攻擊者發送虛假信息,目標主機沒有任何響應時認為端口是開放的,返回數據包認為是關閉的。
如下圖,掃描方發送FIN包,如果端口關閉則返回RST ACK包。

TCP ACK掃描是利用標志位ACK,而ACK標志在TCP協議中表示確認序號有效,它表示確認一個正常的TCP連接。但是在TCP ACK掃描中沒有進行正常的TCP連接過程,實際上是沒有真正的TCP連接。所以使用TCP ACK掃描不能夠確定端口的關閉或者開啟,因為當發送給對方一個含有ACK表示的TCP報文的時候,都返回含有RST標志的報文,無論端口是開啟或者關閉。但是可以利用它來掃描防火墻的配置和規則等。

前面的掃描方法都是針對TCP端口,針對UDP端口一般采用UDP ICMP端口不可達掃描。
如:192.1.14.235對172.16.2.4發送大量UDP端口請求,掃描其開啟UDP端口的情況。

如果對應的UDP端口開啟,則會返回UDP數據包。

如果端口未開啟,則返回“ICMP端口不可達”消息。

NMAP進行操作系統的探測主要用到的是OS探測模塊,使用TCP/IP協議棧指紋來識別不同的操作系統和設備。Nmap內部包含了2600多種已知操作系統的指紋特征,根據掃描返回的數據包生成一份系統指紋,將探測生成的指紋與nmap-os-db中指紋進行對比,查找匹配的操作系統。如果無法匹配,則以概率形式列舉出可能的系統。
如:192.168.1.50對192.168.1.90進行操作系統的掃描探測。首先發起Ping請求,確認主機是否存在。

發起ARP請求,獲取主機MAC地址。

進行端口掃描。

根據綜合掃描情況,判斷操作系統類型。

操作系統的漏洞探測種類很多,本文針對“smb-check-vulns”參數就MS08-067、CVE2009-3103、MS06-025、MS07-029四個漏洞掃描行為進行分析。
攻擊主機:192.168.1.200(Win7),目標主機:192.168.1.40(WinServer 03);
Nmap掃描命令:nmap --script=smb-check-vulns.nse --script-args=unsafe=1 192.168.1.40。

漏洞掃描前,開始對目標主機進行端口掃描。

由于這幾個漏洞多針對SMB服務,下面我們簡單了解一下NAMP掃描行為中的SMB命令。
SMB Command:Negotiate Protocol(0x72):SMB協議磋商
SMB Command: Session Setup AndX(0x73):建立會話,用戶登錄
SMB Command: Tree Connect AndX (0x75):遍歷共享文件夾的目錄及文件
SMB Command: NT Create AndX (0xa2):打開文件,獲取文件名,獲得讀取文件的總長度
SMB Command: Write AndX (0x2f):寫入文件,獲得寫入的文件內容
SMB Command:Read AndX(0x2e):讀取文件,獲得讀取文件內容
SMB Command: Tree Disconnect(0x71):客戶端斷開
SMB Command: Logoff AndX(0x74):退出登錄

(1)MS08-067漏洞掃描部分源碼如下:
function check_ms08_067(host)
if(nmap.registry.args.safe ~= nil) then
return true, NOTRUN
end
if(nmap.registry.args.unsafe == nil) then
return true, NOTRUN
end
local status, smbstate
local bind_result, netpathcompare_result
-- Create the SMB session \\創建SMB會話
status, smbstate = msrpc.start_smb(host, "\\\\BROWSER")
if(status == false) then
return false, smbstate
end
-- Bind to SRVSVC service
status, bind_result = msrpc.bind(smbstate, msrpc.SRVSVC_UUID, msrpc.SRVSVC_VERSION, nil)
if(status == false) then
msrpc.stop_smb(smbstate)
return false, bind_result
end
-- Call netpathcanonicalize
-- status, netpathcanonicalize_result = msrpc.srvsvc_netpathcanonicalize(smbstate, host.ip, "\\a", "\\test\\")
local path1 = "\\AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\..\\n"
local path2 = "\\n"
status, netpathcompare_result = msrpc.srvsvc_netpathcompare(smbstate, host.ip, path1, path2, 1, 0)
-- Stop the SMB session
msrpc.stop_smb(smbstate)
(2)分析
嘗試打開“\\BROWSER”目錄,下一包返回成功。

同時還有其它嘗試,均成功,綜合判斷目標存在MS08-067漏洞。通過Metasploit進行漏洞驗證,成功溢出,獲取Shell。

(1)CVE-2009-3103漏洞掃描部分源碼如下:
host = "IP_ADDR", 445
buff = (
"\x00\x00\x00\x90" # Begin SMB header: Session message
"\xff\x53\x4d\x42" # Server Component: SMB
"\x72\x00\x00\x00" # Negociate Protocol
"\x00\x18\x53\xc8" # Operation 0x18 & sub 0xc853
"\x00\x26"# Process ID High: --> :) normal value should be "\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xfe"
"\x00\x00\x00\x00\x00\x6d\x00\x02\x50\x43\x20\x4e\x45\x54"
"\x57\x4f\x52\x4b\x20\x50\x52\x4f\x47\x52\x41\x4d\x20\x31"
"\x2e\x30\x00\x02\x4c\x41\x4e\x4d\x41\x4e\x31\x2e\x30\x00"
"\x02\x57\x69\x6e\x64\x6f\x77\x73\x20\x66\x6f\x72\x20\x57"
"\x6f\x72\x6b\x67\x72\x6f\x75\x70\x73\x20\x33\x2e\x31\x61"
"\x00\x02\x4c\x4d\x31\x2e\x32\x58\x30\x30\x32\x00\x02\x4c"
"\x41\x4e\x4d\x41\x4e\x32\x2e\x31\x00\x02\x4e\x54\x20\x4c"
"\x4d\x20\x30\x2e\x31\x32\x00\x02\x53\x4d\x42\x20\x32\x2e"
"\x30\x30\x32\x00"
)
(2)分析
十六進制字符串“0x00000000到202e30303200”請求,通過ASCII編碼可以看出是在探測NTLM和SMB協議的版本。無響應,無此漏洞。

(1)MS06-025漏洞掃描部分源碼如下:
--create the SMB session
--first we try with the "\router" pipe, then the "\srvsvc" pipe.
local status, smb_result, smbstate, err_msg
status, smb_result = msrpc.start_smb(host, msrpc.ROUTER_PATH)
if(status == false) then
err_msg = smb_result
status, smb_result = msrpc.start_smb(host, msrpc.SRVSVC_PATH) --rras is also accessible across SRVSVC pipe
if(status == false) then
return false, NOTUP --if not accessible across both pipes then service is inactive
end
end
smbstate = smb_result
--bind to RRAS service
local bind_result
status, bind_result = msrpc.bind(smbstate, msrpc.RASRPC_UUID, msrpc.RASRPC_VERSION, nil)
if(status == false) then
msrpc.stop_smb(smbstate)
return false, UNKNOWN --if bind operation results with a false status we can't conclude anything.
End
(2)分析
先后嘗試去連接“\router”、“ \srvsvc”路徑,均報錯,無RAS RPC服務。


(1)MS07-029漏洞掃描部分源碼如下:
function check_ms07_029(host)
--check for safety flag
if(nmap.registry.args.safe ~= nil) then
return true, NOTRUN
end
if(nmap.registry.args.unsafe == nil) then
return true, NOTRUN
end
--create the SMB session
local status, smbstate
status, smbstate = msrpc.start_smb(host, msrpc.DNSSERVER_PATH)
if(status == false) then
return false, NOTUP --if not accessible across pipe then the service is inactive
end
--bind to DNSSERVER service
local bind_result
status, bind_result = msrpc.bind(smbstate, msrpc.DNSSERVER_UUID, msrpc.DNSSERVER_VERSION)
if(status == false) then
msrpc.stop_smb(smbstate)
return false, UNKNOWN --if bind operation results with a false status we can't conclude anything.
end
--call
local req_blob, q_result
status, q_result = msrpc.DNSSERVER_Query(
smbstate,
"VULNSRV",
string.rep("\\\13", 1000),
1)--any op num will do
--sanity check
msrpc.stop_smb(smbstate)
if(status == false) then
stdnse.print_debug(
3,
"check_ms07_029: DNSSERVER_Query failed")
if(q_result == "NT_STATUS_PIPE_BROKEN") then
return true, VULNERABLE
else
return true, PATCHED
end
else
return true, PATCHED
end
end
(2)分析
嘗試打開“\DNSSERVER”,報錯,未開啟DNS RPC服務。

1、掃描探測可以說是所有網絡中遇到最多的攻擊,因其僅僅是信息搜集而無實質性入侵,所以往往不被重視。但掃描一定是有目的的,一般都是攻擊入侵的前兆。
2、修補漏洞很重要,但如果在掃描層面進行防御,攻擊者就無從知曉你是否存在漏洞。
3、掃描探測一般都無實質性通信行為,同時大量重復性動作,所以在流量監測上完全可以做到阻止防御。