自從電子郵件大大降低了信息的傳播成本,垃圾郵件便隨之而產(chǎn)生。
筆者作為國內(nèi)互聯(lián)網(wǎng)的較早的用戶,使用的是自己注冊的域名的電子郵件地址,從一開始使用至今一直沒有變過,而該郵件地址在國內(nèi)互聯(lián)網(wǎng)發(fā)展初期曾注冊過許多網(wǎng)站服務(wù),因此成為垃圾郵件的目標(biāo)。
筆者的郵件地址在2000年即每天收到近百封垃圾郵件,因此從那時即開始關(guān)注垃圾郵件的控制方法。
2004年1月底,國家四部委聯(lián)合發(fā)文整治垃圾郵件和不良信息,快速啟動了國內(nèi)反垃圾郵件的市場,反垃圾郵件產(chǎn)品廠商風(fēng)起云涌,但筆者認為許多宣傳僅從郵件安全的某個局部出發(fā),失于片面。反垃圾郵件僅僅是郵件安全的一部分技術(shù),郵件安全至少應(yīng)當(dāng)包括反垃圾郵件、反郵件病毒、內(nèi)容過濾等功能,還可能包括郵件溯源、郵件審計等功能。本文由于篇幅所限,只說明反垃圾郵件的技術(shù)。
1. SMTP安全漏洞與垃圾分析
1.1 SMTP起源
在互聯(lián)網(wǎng)上使用的郵件傳輸協(xié)議稱為SMTP(Simple Mail Transfer Protocol簡單郵件傳輸協(xié)議,RFC-821),也許有很多初次了解SMTP協(xié)議的人會奇怪為什么稱為簡單郵件傳輸協(xié)議,那么復(fù)雜郵件傳輸協(xié)議在哪里?如果這樣考慮,可以理解1984年ISO(國際標(biāo)準化組織)和ITU(國際電信聯(lián)盟)發(fā)布的X.400信件傳遞標(biāo)準就是復(fù)雜郵件傳輸協(xié)議(當(dāng)然,其相關(guān)協(xié)議早在近十年前就在討論、完善,只是直到1984年才發(fā)布標(biāo)準)。1982年由互聯(lián)網(wǎng)協(xié)會發(fā)布了基于TCP/IP的SMTP(RFC821)后,隨即發(fā)布了RFC822 ASCII純文本郵件結(jié)構(gòu),這樣就滿足了人們發(fā)送純文本郵件的需求,隨著需求的增長,1996年發(fā)布了一系列MIME(Multipurpos Internet Mail Extensions)格式定義,使電子郵件可以傳遞任意格式的文件,大家發(fā)送郵件時會發(fā)現(xiàn),郵件的大小比附件的大小要大很多,原因就是附件可能經(jīng)過了MIME編碼,導(dǎo)致變大。MIME滿足了人們發(fā)送任意格式郵件的需求,也同時導(dǎo)致了惡意代碼通過電子郵件傳遞。
1.2 郵件發(fā)送過程
一封郵件從發(fā)件人編輯郵件到收件人接收郵件一般要通過如下四步:
1. 發(fā)送客戶端‘(smtp)‘發(fā)送郵件服務(wù)器:發(fā)件人在發(fā)送客戶端(~MUA~,~Mail User Agent~)編輯郵件后發(fā)出,MUA向他定義的發(fā)送郵件服務(wù)器(~MTA~,~Mail Transport Agent~)發(fā)出SMTP請求并握手,發(fā)送郵件服務(wù)器將郵件接收下來放在相關(guān)的郵件隊列中。一般來說,MUA在和發(fā)件MTA握手時,使用的是用戶在MUA該帳號上注冊的郵件帳號信息作為信封Mail From和信頭From的參數(shù),是相同的;
2. 發(fā)送郵件服務(wù)器-->(smtp)-->接收郵件服務(wù)器:發(fā)送郵件服務(wù)器根據(jù)郵件的目的地址,如果目的地址不是本地,則會將郵件轉(zhuǎn)而放到相應(yīng)的發(fā)送隊列中,MTA將郵件從等候的發(fā)送隊列中取出,向接收郵件服務(wù)器發(fā)起SMTP請求并握手,接收郵件服務(wù)器將郵件接收下來,放入相關(guān)的郵件隊列中。一般來說,發(fā)送MTA會把郵件的信封部分和郵件部分(data,包括信頭和信體)分開保存,這樣在與接收MTA通信時,Mail From依然使用原來的信息不變;
3. 接收郵件服務(wù)器dispatch到郵箱:接收郵件服務(wù)器根據(jù)郵件的目的地址(當(dāng)然是本地了),將郵件由MDA(Mail Deliver Agent)放到用戶的郵箱中。接收MTA在和發(fā)送MTA握手時,得到的Mail From數(shù)據(jù)仍然是發(fā)件MUA給出的信息。
4. 郵箱服務(wù)器-->(pop/imap)-->接收客戶端:最后,接收客戶端使用POP或IMAP協(xié)議將郵件下載、閱讀。
1.3 模擬收發(fā)過程
SMTP協(xié)議是TCP/IP協(xié)議的應(yīng)用層協(xié)議,其傳遞的數(shù)據(jù)都是人可讀的數(shù)據(jù),因此可以使用Telnet來仿真、觀察SMTP協(xié)議的握手過程(假設(shè)郵件服務(wù)器IP是192.168.100.100)。
Telnet 192.168.100.100 25 ; 25是TCP/IP協(xié)議給SMTP定義的端口號
<<< 220 smtp.my.com ESMTP Service (SMTP server) ready at 日期、時間 +0800
>>> helo haha.com
<<< 250 smtp.my.com Hello haha.com ([192.168.100.50]), pleased to meet you
>>> mail from:abc@abc.com
<<< 250 abc@abc.com... Sender OK
>>> rcpt to:realname@my.com
<<< 250 realname@my.com... Recipient OK
>>> data
<<< 354 Enter message, end with "." on a line by itself
>>> Reply-to:ccc@ccc.com
>>> From:aaa@aaa.com
>>> To:bbb@bbb.com
>>> Subject:testest
>>>
>>> This is a Test Email.
>>> .
<<< 250 Message accepted for delivery
>>> quit
<<< 221 smtp.my.com SMTP Service closing transmission channel
這樣就用Telnet直接向smtp.my.com送入了一封給realname用戶的郵件。
讓我們來看一下收到的這封郵件的源文件:
Received: from haha.com ([192.168.100.50])
by smtp.my.com (SMTP server)
with SMTP id 2004062314152297-16576 ;
Wed, 23 Jun 2004 14:15:22 +0800
Reply-to:ccc@ccc.com
From:aaa@aaa.com
To:bbb@bbb.com
Subject:testest
X-MIMETrack: Itemize by SMTP Server on Mail/my() at 2004-06-23 14:17:10,
Serialize by POP3 Server on Mail/my() at 2004-06-23 14:18:45,
Serialize complete at 2004-06-23 14:18:45
Date: Wed, 23 Jun 2004 14:17:10 +0800
Message-ID: <OF39FF5AC9.A74F14E2-ON48256EBC.00228835@my.com>
This is a Test Email.
從上面的模擬過程可以看出,該郵件在郵件頭中聲稱郵件來自~aaa@aaa.com~,要發(fā)給bbb@bbb.com;而在SMTP握手中聲稱使用計算機haha.com,郵件來自abc@abc.com,要發(fā)給realname@my.com(這是真正收到該郵件的用戶)。郵件頭的說法和SMTP握手中的說法完全不同,而當(dāng)用戶(~realname@my.com~)收到此郵件時,他所能看到的只是郵件頭中所聲稱的內(nèi)容和發(fā)送該郵件所聲稱的機器名和IP。然而,要使用戶realname收到這封郵件,除了SMTP握手中rcpt to必須是真實的以外,其他所有東西都可以偽造,F(xiàn)rom:和To:都可以不寫。尤其不幸的是:為了返回錯誤提示郵件,SMTP協(xié)議甚至允許mail from:后面是空白。
上面data后的內(nèi)容是真正的郵件,data之前的內(nèi)容是SMTP握手,或稱信封。用戶收到的郵件已沒有信封,但SMTP服務(wù)器可能會根據(jù)信封內(nèi)容在data的信頭部分增加Received數(shù)據(jù)保存一些信封的內(nèi)容。
在郵件客戶端,用戶將看到郵件來自aaa@aaa.com,而回復(fù)時,自動將ccc@ccc.com作為目的地址。
上述郵件模擬發(fā)送過程中,只有收件人地址是真實的(呵呵,否則誰收???);收到的郵件看到的源文件,只有最后一個發(fā)件IP是真實的(前面如果還有,也可能是偽造的)。