一溝絕望的死水:模擬郵件服務器,批量註冊利器

搞事情
這是一溝絕望的死水,清風吹不起半點漪淪。 在這隻許州官放火不許百姓電燈的年代,我們不如一起拿起幾行簡單的 python 代碼,向這死水中多扔些破銅爛鐵。
我們的目標就是把這互聯網搞的更亂更臭,所以我們是不被規則束縛的。今天要拿來開刀的,是郵件系統。

垃圾郵件,很多人都深受其害,但我們今天並不是要搞它。以相反的方式進行思考,我們並不討厭它,而且歡迎它的到來。比如,我要批量註冊一萬個 github 賬號。github 通過郵箱驗證就算註冊成功了,這個時候,我們需要一個郵件服務器,具體流程如下

一溝絕望的死水:模擬郵件服務器,批量註冊利器

這個時候就想啊,能不能把郵件接收這塊給自動化呢?自動化涉及兩個點:
1)要有無窮無盡的郵箱供你使用
2)要非常容易的獲得郵件內容進行解析

稍作思考,一個方案就在腦海中浮現,竟然是超簡單的存在

一溝絕望的死水:模擬郵件服務器,批量註冊利器

其中:
1) 閹割的郵件系統不需要登錄,只管收,不管發
2)郵件系統可以接受帶有某後綴的任意郵件
3)提供簡單的 REST 接口返回郵件 JSON 供解析


下面我們直接進入正題,說一下實現方式。

域名解析配置
打開域名管理,以阿里云爲例,加入兩條信息

加入一條 A 記錄,指向我們將要部署的服務 IP 地址


A    mx   6x.216.2xx.1xx

加入一條 MX 記錄,指向上面配置的收郵件的域名地址。

MX    *   mx.sayhiai.com

注意 *號,意思是所有的域名包括二級域名等,都會被收到。比如 [email protected][email protected]
是不是無窮無盡?
編寫 SMTPD 服務器
使用 python 可以很容易的實現一個 SMTPD 服務器,具體的是使用 aiosmtpd庫。郵件默認收到後是 BASE64 編碼,還分很多部分和類型,解析起來還是比較麻煩的。需要猜解其編碼並遞歸拼接郵件等。代碼片段如下:



def decode_str(s):
   value, charset = decode_header(s)[0]
   if charset:
       value = value.decode(charset)
   return value
def guess_charset(msg):
   charset = msg.get_charset()
   if charset is None:
       content_type = msg.get('Content-Type', '').lower()
       pos = content_type.find('charset=')
       if pos >= 0:
           charset = content_type[pos + 8:].strip()
   return charset
def print_part(msg):
   rs = ""
   content_type = msg.get_content_type()
   if content_type == 'text/plain' or content_type == 'text/html':
       content = msg.get_payload(decode=True)
       charset = guess_charset(msg)
       if charset:
           content = content.decode(charset)
       rs = rs + str(content)
   else:
       rs = rs + str(content_type)
   return rs
def print_info(msg):
   rs = ""
   if (msg.is_multipart()):
       parts = msg.get_payload()
       for n, part in enumerate(parts):
           if part.is_multipart():
               rs = rs + print_info(part)
           else:
               rs = rs + print_part(part)
   else:
       return print_part(msg)
   return rs

編寫 REST 服務
解析完郵件後,我們把內容存放在 sqlite3 中。接下來就是編寫數據接口了。

我們的目的是儘量方便郵件的獲取, REST+json是首選的。python 的 flask庫無疑是最簡單最適合的。

import json
from flask import Flask
from flask import send_file
from data import dataInstance
app = Flask(__name__)
dao = dataInstance
def web_start(host, port):
   app.run(host=host, port=port)
@app.route('/')
def index():
   return send_file('static/index.html')
@app.route('/all')
def msg_all():
   rows = dao.read_all()
   return json.dumps(rows)
@app.route('/from/<addr>')
def msg_from(addr):
   rows = dao.read_from(addr)
   return json.dumps(rows)
@app.route('/to/<addr>')
def msg_to(addr):
   rows = dao.read_to(addr)
   return json.dumps(rows)

如你所見,提供了三個接口
1)/all 獲取所有郵件
2) /from/{addr} 根據發送方查找郵件
3) /to/{addr} 根據接收方查找郵件


每次查詢做多返回 100 條記錄,反正多了你也用不着。

試驗一下
使用 [email protected] 註冊一個賬號。使用 curl 或者瀏覽器獲取郵件信息:

curl 
-
XGET http
:
//sayhiai.com:14000/to/[email protected]

或者使用 http://sayhiai.com:14000/ 在線查詢一下。

 我的太慢,記得自己搭建一個啊,別忘了 SMTPD 的端口是 25,綁定其他的是不行的

結尾
至此, 一個完美的閉環完成了。我記的前段時間某些同學還對微軟收購 github 心存不滿,是時候給你一個發泄的途徑了,注意多弄幾個 ip。

你瞧瞧你瞧瞧,即使 github 這麼大的一個網站,僅僅郵箱驗證就通過了,可以預見網絡上有多少的網站可以使用相同的思路去搞。

我已經把代碼放到 github 上了 :) :) :). https://github.com/lycying/crazy-email-recv-srv ,對你有幫助的話別忘了關注微信公衆號 小姐姐味道,如果順便打賞幾毛錢,那是最妙不過了。要是你幹了壞事的話,就先不要留名了~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章