SMTP Sniffing
Merhaba,
SMTP ile gönderilen epostaların RFC2821’e göre standart yapısı şu şekildedir:
- Oturum açma ve gönderen-alıcı girişi
- Mesaj başlığı
- Mesaj gövdesi
- Oturum kapatma
Mesaj başlığı bölümü DATA\r\n ile başlar ve \r\n\r\n ile biter, mesaj gövdesi ise \r\n.\r\n ile (aradaki nokta önemli) biter. Örnek bir SMTP transferi şu şekildedir:
Bölüm 1 başlangıcı 220 bilgiin.com ESMTP EHLO [192.168.5.205] 250-hmailserver 250-SIZE 250 AUTH LOGIN AUTH LOGIN 334 xxx xxx 334 xxx xxx 235 authenticated. MAIL FROM:<[email protected]> SIZE=376 250 OK RCPT TO:<[email protected]> 250 OK DATA 354 OK, send. Bölüm 2 başlangıcı Message-ID: <[email protected]> Date: Sat, 11 Dec 2010 10:56:04 +0200 From: =?ISO-8859-9?Q?Gonderen Adi?= <[email protected]> User-Agent: Thunderbird 2.0.0.24 (X11/20100411) MIME-Version: 1.0 To: =?ISO-8859-9?Q?Alici Adi?= <[email protected]> Subject: aa Content-Type: text/plain; charset=ISO-8859-9; format=flowed Content-Transfer-Encoding: 7bit Bölüm 3 başlangıcı mesaj gövdesi Bölüm 4 başlangıcı . 250 Queued (0.031 seconds) QUIT 221 goodbye
Bu örneğin başlık bölümüne baktığınızda gönderen ve alıcı gibi bilgileri kolaylıkla görebilirsiniz.
Birden fazla alıcı olduğunda ise alıcıların yazıldığı satırlar 80 karakter ile sınırlı kalmak koşuluyla alıcılar birden fazla satıra yazılır ve ilk satırdan sonraki alıcı satırlarının başında #32 (boşluk karakteri) bulunur. Örneğin:
To: [email protected], [email protected] , [email protected]
Dolayısıyla bir SMTP mesajını ayrıştırırken To: alanında birden fazla alıcı olduğu dikkate alınmalı, To: başlangıcından sonraki satırlarda boşluk karakteri olup olmadığına bakılmalıdır.
Ancak tüm eposta istemcisi uygulamalar RFC2821’e göre hareket etmez. Bu standarda uymayanlardan birisi de Microsoft Outlook 2007 uygulamasıdır. Outlook 2007 RFC2821’de bulunmayan başlık alanları eklemekle kalmaz, birden fazla alıcı için de standardın dışında bir yöntem kullanır. Tek alıcısı olan bir epostaya örnek şu şekildedir:
Content-class: urn:content-classes:message MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----_=_NextPart_001_01CB9793.DF23CF26" X-MimeOLE: Produced By Microsoft Exchange V6.5 Subject: RE: subject Date: Thu, 9 Dec 2010 13:26:06 +0200 Message-ID: <xxx> X-MS-Has-Attach: X-MS-TNEF-Correlator: Thread-Topic: AD-R 2060 (S49376) Thread-Index: AcuXkAB9XTO2/OQsSB6/f+m0vHSVmQAA9j7g References: <xyz> From: "abc" <[email protected]> To: =?utf-8?B?JRd1LQNPNkLQNPYQN9L=?= <[email protected]>
Birden fazla alıcı söz konusu olduğunda ise To: alanında ilk satırdan sonraki satırların başına \t (sekme) karakteri kullanır:
To: =?iso-8859-9?Q?Alici Adi?= <[email protected]>, <[email protected]>, "Alici Uc" <[email protected]>, <[email protected]>
Dolayısıyla SMTP ile giden bir epostanın ayrıştırılması sırasında RFC2821’de belirtilenlerin dışında ek kontroller koymak gerekir. C ile yazılmış örnek bir ayrıştırıcı şuna benzer bir kod kullanabilir:
if ((strncmp(payload, "Message-ID: ", 12) == 0) || (strncmp(payload, "Message-ID: ", 12) != NULL)){
/* Eğer Message-ID ile başlamışsa (standart) ya da içerisinde Message-ID geçiyorsa (Outlook) */
....
/* To: kısmını almak için gereken kod */
if ((p = strstr(payload, "To: ")) != NULL && p < s) {
__cont1:
for (; *p != '\r' && *p != ''; p++) {
fputc(*p, mail_fp);
fputc(*p, mail_fp2);
}
if (p != NULL) {
p = p + 2;
if ((*p != '' && *p == ' ') || (*p != '' && *p == '\t')) {
/* satırın ilk karakteri #32 (boşluk) ise (standart) veya \t (sekme) ise (Outlook) */
p++;
goto __cont1;
}
}
}