機器學習實戰(zhàn)之CSIC2010網(wǎng)絡(luò)攻擊數(shù)據(jù)

2019年十月份左右顷链,迫于學業(yè)上的壓力開始入坑機器學習属提,到現(xiàn)在大約有小半年的時間了。這期間從數(shù)據(jù)挖掘分析到機器學習的原理和算法等等看了很多東西络拌,但是一直感覺它們只是被迫塞進了腦子里并沒有進行消化吸收奋隶。這個時候最需要自己給自己找點事來做了:)由于之前對Web安全有一點點了解擂送,就決定從Web應(yīng)用產(chǎn)生的HTTP數(shù)據(jù)流量進行一次機器學習的實戰(zhàn)。

GitHub地址:https://github.com/zambery/Machine-Learning-on-CSIC-2010


1 數(shù)據(jù)集及預(yù)處理

實驗使用 HTTP CSIC 2010 數(shù)據(jù)集唯欣。該數(shù)據(jù)集由西班牙最高科研理事會 CSIC 在論文 _Application of the Generic Feature __Selection Measure in Detection of Web _Attacks 中作為附件給出的嘹吨,是一個電子商務(wù)網(wǎng)站的訪問日志,包含 36000 個正常請求和 25000 多個攻擊請求境氢。異常請求樣本中包含 SQL 注入蟀拷、文件遍歷、CRLF 注入萍聊、XSS问芬、SSI 等攻擊樣本。
數(shù)據(jù)集下載鏈接:http://www.isi.csic.es/dataset/

HTTP CSIC 2010 數(shù)據(jù)集單個樣本為如下格式:
image

根據(jù)觀察寿桨,該數(shù)據(jù)集除路徑(URI)和參數(shù)外其他 Header 無任何攻擊 Payload此衅,具有很多冗余信息。因此對該數(shù)據(jù)集進行格式化亭螟,只保留 HTTP 方法挡鞍、路徑和參數(shù)。

import urllib.parse

normal_file_raw = 'normalTrafficTraining/normalTrafficTraining.txt'
anomalous_file_raw = 'anomalousTrafficTest/anomalousTrafficTest.txt'

normal_file_pre = 'normal.txt'
anomalous_file_pre = 'anomalous.txt'


def pre_file(file_in, file_out=None):
    with open(file_in, 'r', encoding='utf-8') as f_in:
        lines = f_in.readlines()
    res = []
    for i in range(len(lines)):
        line = lines[i].strip()
        # 提取 GET類型的數(shù)據(jù)
        if line.startswith("GET"):
            res.append("GET " + line.split(" ")[1])
        # 提取 POST類型的數(shù)據(jù)
        elif line.startswith("POST") or line.startswith("PUT"):
            method = line.split(' ')[0]
            url = line.split(' ')[1]
            j = 1
            # 提取 POST包中的數(shù)據(jù)
            while True:
                # 定位消息正文的位置
                if lines[i + j].startswith("Content-Length"):
                    break
                j += 1
            j += 2
            data = lines[i + j].strip()
            url += '?'+data
            res.append(method + ' ' + url)

    with open(file_out, 'w', encoding='utf-8') as f_out:
        for line in res:
            line = urllib.parse.unquote(line, encoding='ascii', errors='ignore').replace('\n', '').lower()
            f_out.writelines(line + '\n')

    print("{}數(shù)據(jù)預(yù)提取完成 {}條記錄".format(file_out, len(res)))


if __name__ == '__main__':
    pre_file(normal_file_raw, normal_file_pre)
    pre_file(anomalous_file_raw, anomalous_file_pre)

格式化后的數(shù)據(jù)如下:
image

異常流量下載:anomalous.txt
正常流量下載:normal.txt

2 特征提取

經(jīng)過上面的處理我們有了格式化的文本數(shù)據(jù)预烙,但是如果想要運用機器學習的方法墨微,單單做到這里是不夠的,我們還需要進一步地對這里的文本數(shù)據(jù)進行特征提取扁掸。一個 Web 訪問記錄的成分是比較固定的翘县,每個部分(方法、路徑谴分、參數(shù)锈麸、HTTP 頭、Cookie 等)都有比較好的結(jié)構(gòu)化特點狸剃,因此可以把 Web 攻擊識別任務(wù)抽象為文本分類任務(wù)掐隐。這里我們采用兩鐘方法進行特征提取。

2.1 TF-IDF

對文本數(shù)據(jù)進行分類钞馁,常用的方法有詞袋模型虑省、TF-IDF、詞向量化等方法僧凰。由于只是一次簡單的知識梳理實驗探颈,這里就不對其進行比較驗證了,直接選擇TF-IDF對文本數(shù)據(jù)進行向量化處理训措。

在進行向量化處理之前伪节,先對文本數(shù)據(jù)進行整合、打標簽的操作

def load_data(file):
    with open(file, 'r', encoding='utf-8') as f:
        data = f.readlines()
    result = []
    for d in data:
        d = d.strip()
        if len(d) > 0:
            result.append(d)
    return result

normal_requests = load_data('normal.txt')
anomalous_requests = load_data('anomalous.txt')

all_requests = normal_requets + anomalous_requets
y_normal = [0] * len(normal_requests)
y_anomalous = [1] * len(anomalous_requests)
y = y_normal + y_anomalous

之后采用TF-IDF進行特征提取

from sklearn.feature_extraction.text import TfidfVectorizer

vectorizer = TfidfVectorizer(min_df=0.0, analyzer="word", sublinear_tf=True)
X = vectorizer.fit_transform(all_requests)

我們查看下一提取的特征向量:
image

其特征矩陣為:
image

可以看到特征維度為33550绩鸣,這樣一個維度對于很多機器算法來說計算復(fù)雜度太高怀大,也很容易產(chǎn)生過擬合的情況。

當然遇到這種情況呀闻,應(yīng)該采用相應(yīng)的手段對其進行降維操作化借,但是由于機器限制在保留90%信息的情況下得出所需的維度需要相當長的時間,故直接采用這一維度進行實驗捡多。

2.2 自定義特征向量

在上面用TF-IDF進行特征提取時蓖康,遇到的問題是數(shù)據(jù)的維度太高,雖然我們還沒有用機器學習算法進行實際的訓(xùn)練但是這樣高的維度讓我們應(yīng)該考慮一些備用方案垒手,比如嘗試進行提取自定義的特征蒜焊。

這里我們不妨對最初的文本數(shù)據(jù)進行如下的特征提取:

  • URL長度
  • 請求類型
  • 參數(shù)部分長度
  • 參數(shù)的個數(shù)
  • 參數(shù)的最大長度
  • 參數(shù)的數(shù)字個數(shù)
  • 參數(shù)值中數(shù)字所占比例
  • 參數(shù)值中字母所占比例
  • 特殊字符個數(shù)
  • 特殊字符所占比例
def vector(data):
    feature = []

    for i in range(len(data)):
        # 采用 split("?", 1)是為了處理形如 http://127.0.0.1/?open=?123的URL
        s = data[i].split("?", 1)
        if len(s) != 1:

            url_len = len(data[i])

            method = data[i].split(" ")[0]
            if method == "get":
                url_method = 1
            elif method == "post":
                url_method = 2
            else:
                url_method = 3

            query = s[1]
            parameter_len = len(query)
            parameters = query.split("&")
            parameter_num = len(parameters)

            parameter_max_len = 0
            parameter_number_num = 0
            parameter_str_num = 0
            parameter_spe_num = 0
            par_val_sum = 0

            for parameter in parameters:
                try:
                    # 采用 split("=", 1)是為了處理形如 open=123=234&file=op的參數(shù)
                    [par_name, par_val] = parameter.split("=", 1)
                except ValueError as err:
                    # 處理形如 ?open 這樣的參數(shù)
                    print(err)
                    print(data[i])
                    break

                par_val_sum += len(par_val)
                if parameter_max_len < len(par_val):
                    parameter_max_len = len(par_val)
                parameter_number_num += len(re.findall("\d", par_val))
                parameter_str_num += len(re.findall(r"[a-zA-Z]", par_val))
                parameter_spe_num += len(par_val) - len(re.findall("\d", par_val)) - len(
                    re.findall(r"[a-zA-Z]", par_val))

            try:
                parameter_number_rt = parameter_number_num / par_val_sum
                parameter_str_rt = parameter_str_num / par_val_sum
                parameter_spe_rt = parameter_spe_num / par_val_sum
                feature.append([url_len, url_method, parameter_len, parameter_num,
                                parameter_max_len, parameter_number_num, parameter_str_num,
                                parameter_spe_num, parameter_number_rt, parameter_str_rt,
                                parameter_spe_rt])
            except ZeroDivisionError as err:
                print(err)
                print(data[i])
                continue
    return feature

自定義好后的數(shù)據(jù)用 numpy 形式保存泳梆,方便以后直接使用。
向量化的正常數(shù)據(jù):vector_normal.txt
向量化的異常數(shù)據(jù):vector_anomalous.txt

同樣地榜掌,我們也需要整合已經(jīng)向量化好的數(shù)據(jù)鸭丛,并進行打標簽操作,劃分測試集和訓(xùn)練集唐责。

# 整合數(shù)據(jù)鳞溉,打標簽
import numpy as np

normal = np.loadtxt("vector_normal")
anomalous = np.loadtxt("vector_anomalous")

all_requests = np.concatenate([normal, anomalous])
X = all_requests

y_normal = np.zeros(shape=(normal.shape[0]), dtype='int')
y_anomalous = np.ones(shape=(anomalous.shape[0]), dtype='int')
y = np.concatenate([y_normal, y_anomalous])

# 劃分測試集和訓(xùn)練集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=666)

3 模型訓(xùn)練

這部分我們主要比較TF-IDF提取的特征和自定義提取的特征在模型訓(xùn)練中的不同

3.1 k近鄰算法

在開始之前先對數(shù)據(jù)進行歸一化操作,進一步提高模型訓(xùn)練結(jié)果的正確性:

from sklearn.preprocessing import StandardScaler

# 數(shù)據(jù)歸一化
standardScalar = StandardScaler()
standardScalar.fit(X_train)
X_train = standardScalar.transform(X_train)
X_test_std = standardScalar.transform(X_test)

在進行模型訓(xùn)練時鼠哥,我們將采用網(wǎng)格搜索的方法熟菲,使用交叉驗證的方式來評估超參數(shù)的所有可能的組合:

# 網(wǎng)格搜索的參數(shù)
param_grid = [
    {
        'weights': ['uniform'],
        'n_neighbors': [i for i in range(2, 11)] #從1開始容易過擬合
    },
    {
        'weights': ['distance'],
        'n_neighbors': [i for i in range(2, 11)],
        'p': [i for i in range(1, 6)]
    }
]

# cv其實也是一個超參數(shù),一般越大越好朴恳,但是越大訓(xùn)練時間越長
grid_search = GridSearchCV(KNeighborsClassifier(), param_grid, n_jobs=-1, cv=5)

基于上面的設(shè)置可以得到如下表所示結(jié)果抄罕,其中TF-IDF使用無法得出結(jié)果(內(nèi)存爆表死機),只進行了單個模型訓(xùn)練于颖,模型參數(shù)如下:

KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
                     metric_params=None, n_jobs=None, n_neighbors=5, p=2,
                     weights='uniform')
自定義特征 TF-IDF
訓(xùn)練時間 47.1 s 60 ms
最佳結(jié)果 'n_neighbors': 10<br />'p': 3,<br />'weights': 'distance'
grid_search.best_score_ 0.8759619101163076
測試集score 0.8733661278988053 0.9233603537214443
精準率 0.8785353535353535 0.9194262813752373
召回率 0.8922800718132855 0.8872379401587625
F1-Score 0.8853543707850872 0.9030453697949038

3.2 邏輯回歸

# 網(wǎng)格搜索的參數(shù)
param_grid = [
    {
        'C': [0.1, 1, 3, 5, 7],
        'penalty': ['l1', 'l2']
    }
]

grid_search = GridSearchCV(LogisticRegression(), param_grid, n_jobs=-1, cv=5)
自定義特征 TF-IDF
訓(xùn)練時間 4min 11s 1min 31s
最佳結(jié)果 'C': 7<br />'penalty': 'l1' 'C': 7<br />'penalty': 'l2'
grid_search.best_score_ 0.6869882989563935 0.9680463440596087
測試集score 0.6929023190442727 0.9737165315647262
精準率 0.7455587392550144 0.9922813036020584
召回率 0.6673506027186458 0.941990637085284
F1-Score 0.7042901610502098 0.9664821969301451

上面的結(jié)果還是有點出乎意料的

  • 邏輯回歸模型的訓(xùn)練時間竟然比k近鄰還長呆贿,這當然可能跟網(wǎng)格搜索所設(shè)置的參數(shù)有關(guān)系,但是這一點與理論沖突,仍有待后期驗證
  • 由TF-IDF所提取的特征向量不僅訓(xùn)練時間快做入,模型的準確率也比自定義的特征提取高出不少冒晰,這里有些反直覺,具體原因也不明確
  • 對于自定義特征的在邏輯回歸上的訓(xùn)練結(jié)果竟块,可以考慮增加多項式特征來進行優(yōu)化

3.3 決策樹

對于決策樹來說可以直接使用原始數(shù)據(jù)而不必進行特征縮放

# 網(wǎng)格搜索的參數(shù)
param_grid = [
    {
        'max_depth':[i for i in range(1, 10)],
        'min_samples_leaf':[i for i in range(1, 20)],
        'min_samples_split':[i for i in range(10, 30)],
    }
]
自定義特征 TF-IDF
訓(xùn)練時間 3min 46s 1h 7min 6s
最佳參數(shù) 'max_depth': 9<br />'min_samples_leaf': 1<br />'min_samples_split': 27 'max_depth': 9<br />'min_samples_leaf': 19<br />'min_samples_split': 10
grid_search.best_score_ 0.7973224638954285 0.8979775648898715
測試集score 0.8042164441321152 0.90084336362892
精準率 0.7658039881204921 0.951904296875
召回率 0.9258784303667608 0.7936087929981681
F1-Score 0.8382677348194589 0.8655788655788657

從上面的結(jié)果可以看出由于TF-IDF所提取的特征維度太大壶运,因此訓(xùn)練時間達到了一個小時。

3.4 SVM

SVM對特征縮放較為敏感浪秘,因此我們在進行模型訓(xùn)練之前需要對數(shù)據(jù)進行歸一化處理

# 網(wǎng)格搜索的參數(shù)
param_grid = [
    {
        'kernel': ["poly"],
        'degree': [1, 2, 3],
        'C': [0.1, 1, 3, 5]
    }
]

grid_search = GridSearchCV(SVC(), param_grid, n_jobs=-1, cv=5)

此外由于SVM的對于數(shù)據(jù)量較多的數(shù)據(jù)集訓(xùn)練時間較慢蒋情,此處TF-IDF的特征提取結(jié)果沒有進行網(wǎng)格搜索尋找最佳參數(shù),其模型參數(shù)如下:

SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
    decision_function_shape='ovr', degree=3, gamma='auto_deprecated',
    kernel='rbf', max_iter=-1, probability=False, random_state=None,
    shrinking=True, tol=0.001, verbose=False)
自定義特征 TF-IDF
訓(xùn)練時間 8min 26s 10min 22s
最佳參數(shù) 'C': 5<br />'degree': 3<br />'kernel': 'poly'
grid_search.best_score_ 0.7022734460100496
測試集score 0.7114546732255798 0.9619258167526407
精準率 0.7404898384575299 0.9623700623700624
召回率 0.7289048473967684 0.9421941787095461
F1-Score 0.7346516737753651 0.9521752545510646

3.5 隨機森林

由于隨機森林模型所需的訓(xùn)練時間較長耸携,這里就不采用網(wǎng)格搜索的方式尋找最佳參數(shù)了棵癣,進行訓(xùn)練的隨機森林模型參數(shù)如下:

RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',
                       max_depth=None, max_features='auto', max_leaf_nodes=None,
                       min_impurity_decrease=0.0, min_impurity_split=None,
                       min_samples_leaf=1, min_samples_split=2,
                       min_weight_fraction_leaf=0.0, n_estimators=500,
                       n_jobs=-1, oob_score=True, random_state=666, verbose=0,
                       warm_start=False)
自定義特征 TF-IDF
訓(xùn)練時間 3.77 s 2min 50s
測試集score 0.947013352073085 0.9647916154916892
精準率 0.9471813103098019 0.9618792499484855
召回率 0.956655552705822 0.9501323020557704
F1-Score 0.9518948577261708 0.9559696907638747

4 總結(jié)

這次實驗分別使用了自定義的特征向量和TF-IDF提取的特征向量進行模型訓(xùn)練,我們不妨從以下幾個方面來回顧一下模型的訓(xùn)練結(jié)果

實驗結(jié)果分析

  • 訓(xùn)練時間:

從訓(xùn)練時間上看夺衍,用自定義特征進行模型訓(xùn)練所花費的時間總體要比TF-IDF提取特征進行模型訓(xùn)練所花費的時間短狈谊。當然由于有些使用了網(wǎng)格搜索尋找最佳參數(shù),有些沒有進行網(wǎng)格搜索刷后,這里無法進行定量的分析的畴。因為TF-IDF的特征維度—33550,遠遠超過自定義的特征維度—11尝胆,自定義特征的模型訓(xùn)練時間短也是可以預(yù)見的丧裁。

但在邏輯回歸中,基于相同的網(wǎng)格搜索參數(shù)含衔,自定義特征的模型訓(xùn)練時間:4min 11s煎娇、TF-IDF提取特征的模型訓(xùn)練時間:1min 31s。自定義特征的模型訓(xùn)練時間較長贪染,這一點目前無法解釋缓呛。

  • 訓(xùn)練結(jié)果:

自定義特征的模型(藍色為最大值,綠色為次大值)

k近鄰 邏輯回歸 決策樹 SVM 隨機森林
測試集score 0.8733661278988053 0.6929023190442727 0.8042164441321152 0.7114546732255798 0.947013352073085
精準率 0.8785353535353535 0.7455587392550144 0.7658039881204921 0.7404898384575299 0.9471813103098019
召回率 0.8922800718132855 0.6673506027186458 0.9258784303667608 0.7289048473967684 0.956655552705822
F1-Score 0.8853543707850872 0.7042901610502098 0.8382677348194589 0.7346516737753651 0.9518948577261708

提取特征的模型訓(xùn)練(藍色為最大值杭隙,綠色為次大值)

k近鄰 邏輯回歸 決策樹 SVM 隨機森林
測試集score 0.9233603537214443 0.9737165315647262 0.90084336362892 0.9619258167526407 0.9647916154916892
精準率 0.9194262813752373 0.9922813036020584 0.951904296875 0.9623700623700624 0.9618792499484855
召回率 0.8872379401587625 0.941990637085284 0.7936087929981681 0.9421941787095461 0.9501323020557704
F1-Score 0.9030453697949038 0.9664821969301451 0.8655788655788657 0.9521752545510646 0.9559696907638747
  1. 通過上面兩張表的對比可以看出哟绊,隨機森林作為一種集成學習算法其在兩種特征提取方法種均有較好的表現(xiàn),但其單個模型的訓(xùn)練時間均較長痰憎。
  2. 由于TF-IDF提取的特征維度為33550票髓,所以上述每個訓(xùn)練模型都取得較好結(jié)果;但是自定義特征僅僅選取了11個維度铣耘,如果添加更多的特征維度其模型訓(xùn)練的性能和效果將會超過TF-IDF洽沟。
  3. 在特征維度較大的情況下,邏輯回歸不論在性能和效果上仍然有較好的表現(xiàn)蜗细,這一點值得進行后續(xù)的探討裆操。
  4. 在自定義的特征維度下,即特征維度僅為11時,k近鄰算法的表現(xiàn)最好踪区,預(yù)測結(jié)果不具有可解釋性昆烁。

心得體會

通過上面的實驗也可以看出,數(shù)據(jù)對機器學習的算法影響很大朽缴,選擇什么樣的方法進行特征提取善玫,對后續(xù)的模型訓(xùn)練至關(guān)重要水援。

以我自己目前的理解和水平密强,后續(xù)一段時間進行機器學習這一領(lǐng)域的探索可以從以下三個方面來入手:

  • 一是針對數(shù)據(jù)進行更好特征提取,比如這次實驗中的數(shù)據(jù)蜗元,對HTTP攻擊的理解越深入我們越能對其進行特征描述或渤,最終高度刻畫HTTP的攻擊流量。此外奕扣,不限于HTTP的攻擊流量薪鹦,如果針對網(wǎng)絡(luò)流量包進行深入的刻畫、分析惯豆,并能總結(jié)出一種類似TF-IDF的特征提取模型也是極好的池磁。
  • 二是深入理解現(xiàn)有的機器算法。以這次的實驗為例楷兽,邏輯回歸為什么在特征維度極大的數(shù)據(jù)集中仍然有較好的表現(xiàn)地熄?針對現(xiàn)有的特征向量如何結(jié)合模型的設(shè)計原理尋找最佳參數(shù),而不是通過網(wǎng)格搜索漫無目的地遍歷芯杀?這些問題都依賴于對機器算法更深入的了解端考。
  • 三是探索更高階的機器學習算法,比如深度學習揭厚。從本次的實驗可以看出却特,傳統(tǒng)的機器學習方法依賴于特征工程,需要人為地進行特征提壬冈病裂明;但是深度學習可以自動地找出這個分類問題所需要的重要特征,因此探索深度學習的算法也可以作為后續(xù)的學習方向太援。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末闽晦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子粉寞,更是在濱河造成了極大的恐慌尼荆,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件唧垦,死亡現(xiàn)場離奇詭異捅儒,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門巧还,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鞭莽,“玉大人,你說我怎么就攤上這事麸祷∨炫” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵阶牍,是天一觀的道長喷面。 經(jīng)常有香客問我,道長走孽,這世上最難降的妖魔是什么惧辈? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮磕瓷,結(jié)果婚禮上盒齿,老公的妹妹穿的比我還像新娘。我一直安慰自己困食,他們只是感情好边翁,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著硕盹,像睡著了一般符匾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上莱睁,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天待讳,我揣著相機與錄音,去河邊找鬼仰剿。 笑死创淡,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的南吮。 我是一名探鬼主播琳彩,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼部凑!你這毒婦竟也來了露乏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤涂邀,失蹤者是張志新(化名)和其女友劉穎瘟仿,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體比勉,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡劳较,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年驹止,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片观蜗。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡臊恋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出墓捻,到底是詐尸還是另有隱情抖仅,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布砖第,位于F島的核電站撤卢,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏厂画。R本人自食惡果不足惜凸丸,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一拷邢、第九天 我趴在偏房一處隱蔽的房頂上張望袱院。 院中可真熱鬧,春花似錦瞭稼、人聲如沸忽洛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽欲虚。三九已至,卻和暖如春悔雹,著一層夾襖步出監(jiān)牢的瞬間复哆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工腌零, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留梯找,地道東北人。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓益涧,卻偏偏與公主長得像锈锤,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子闲询,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容