如何破解亂序拼圖驗(yàn)證碼

一雏节、前言

亂序拼圖驗(yàn)證是一種較少見(jiàn)的驗(yàn)證碼防御醇坝,市面上更多的是拖動(dòng)滑塊邑跪,被完美攻克的有不少,都在行為軌跡上下足了功夫呼猪,本文不討論軌跡模擬范疇画畅,就只針對(duì)拼圖還原進(jìn)行研究

找一個(gè)市面比較普及的頂像亂序拼圖進(jìn)行驗(yàn)證宋距,它號(hào)稱的防御能力4星轴踱,用戶體驗(yàn)3星,通過(guò)研究發(fā)現(xiàn)谚赎,它的還原程度相當(dāng)高淫僻,思路也很簡(jiǎn)單,下面一步步的講解還原過(guò)程壶唤。

二雳灵、環(huán)境準(zhǔn)備

1.依賴

  • 采集模擬 selenium
  • 特征匹配 python+opencv

2.安裝環(huán)境

pip install setuptools
pip install selenium
pip install numpy Matplotlib
pip install opencv-python

3.chormedriver 下載

找到對(duì)應(yīng)瀏覽器版本+系統(tǒng)平臺(tái)的driver后,macOS 建議存放到** /usr/local/bin**

wget https://npm.taobao.org/mirrors/chromedriver/95.0.4638.69/chromedriver_mac64.zip

三闸盔、采集樣本

引入依賴庫(kù)悯辙,使用 webdriver 打開(kāi)官方網(wǎng)站的產(chǎn)品演示頁(yè)面

import os
import cv2
import time
import urllib.request
import matplotlib.pyplot as plt
import numpy as np

from PIL import Image
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

創(chuàng)建下載樣本的代碼,主要流程是打開(kāi)官網(wǎng)的demo頁(yè)后迎吵,截圖并保存

# 采集代碼
class CrackPuzzleCaptcha():
    # 初始化webdriver
    def init(self):
        self.url = 'https://www.dingxiang-inc.com/business/captcha'
        chrome_options = webdriver.ChromeOptions()
        # chrome_options.add_argument("--start-maximized")
        chrome_options.add_experimental_option("excludeSwitches", ["ignore-certificate-errors","enable-automation"]) # 設(shè)置為開(kāi)發(fā)者模式
        path = r'/usr/local/bin/chromedriver' #macOS
#         path = r'D:\Anaconda3\chromedriver.exe' #windows
        self.browser = webdriver.Chrome(executable_path=path,chrome_options=chrome_options)
        #設(shè)置顯示等待時(shí)間
        self.wait = WebDriverWait(self.browser, 20)
        self.browser.get(self.url)
    # 打開(kāi)驗(yàn)證碼demo頁(yè)面躲撰,并強(qiáng)制元素在瀏覽器可視區(qū)域
    def openTest(self):
        time.sleep(1)
        self.browser.execute_script('setTimeout(function(){document.querySelector("body > div.wrapper-main > div.wrapper.wrapper-content > div > div.captcha-intro > div.captcha-intro-header > div > div > ul > li.item-8").click();},0)')
        self.browser.execute_script('setTimeout(function(){document.querySelector("body > div.wrapper-main > div.wrapper.wrapper-content > div > div.captcha-intro > div.captcha-intro-body > div > div.captcha-intro-demo").scrollIntoView();},0)')
        time.sleep(1)
    # 找到原圖,webp格式钓觉,直接下載保存
    def download(self):
        onebtn = self.browser.find_element_by_css_selector('#dx_captcha_oneclick_bar-logo_2 > span')
        ActionChains(self.browser).move_to_element(onebtn).perform() 
        time.sleep(1)
        #下載webp
        img_url = self.browser.find_element_by_css_selector('#dx_captcha_jigsaw_fragment-top-left_3 > img').get_attribute("src")
        img_address = "test.png" # 樣本文件
        response = urllib.request.urlopen(img_url)
        img = response.read()
        with open(img_address, 'wb') as f:
            f.write(img)
            print('已保存', img_address)
        return self.browser

    def crack(self):
        pass

開(kāi)始采集

crack = CrackPuzzleCaptcha()
crack.init()
crack.openTest()
browser2 = crack.download()

已保存 test.png

四茴肥、調(diào)研結(jié)果

  • 關(guān)鍵1:顯示的拼圖的原圖就是已經(jīng)亂序的狀態(tài)
  • 關(guān)鍵2:原圖是一個(gè)整體,那么獲取原圖切割并編號(hào)荡灾,能得到與拼圖過(guò)程一致的結(jié)果
  • 關(guān)鍵3:拼圖只需要做1次換位即可,2x2的矩陣,可以對(duì)[1,2,3,4]進(jìn)行排列組合批幌,得到所有的拼接結(jié)果

五础锐、分析過(guò)程

1.輔助函數(shù)

定義輔助函數(shù),方便獲取參數(shù)

# 顯示圖形
def show_images(images: list , title = '') -> None:
    if title!='':
        print(title)
    n: int = len(images)
    f = plt.figure()
    for i in range(n):
        f.add_subplot(1, n, i + 1)
        plt.imshow(images[I])
    plt.show(block=True)

# 獲取圖像的基本信息
def getSize(p):
    sum_rows = p.shape[0]
    sum_cols = p.shape[1]
    channels = p.shape[2]
    return sum_rows,sum_cols,channels

2.圖像切割

# 輸入樣本
file = 'test.png'
img = cv2.imread(file)

sum_rows,sum_cols,channels = getSize(img)
part_rows,part_cols = round(sum_rows/2),round(sum_cols/2)
print('樣本圖 高度荧缘、寬度皆警、通道',sum_rows,sum_cols,channels)
print('四圖切分,求原圖中心位置',part_rows,part_cols)

part1 = img[0:part_rows, 0:part_cols]
part2 = img[0:part_rows, part_cols:sum_cols]
part3 = img[part_rows:sum_rows, 0:part_cols]
part4 = img[part_rows:sum_rows, part_cols:sum_cols]

print('切割為4個(gè)小塊的 W/H/C 信息截粗,并四圖編號(hào):左上=1信姓,右上=2,左下=3绸罗,右下=4\n',getSize(part1),getSize(part2),getSize(part3),getSize(part4))

show_images([img],'原圖')
show_images([part1,part2],'切割圖')
show_images([part3,part4])

輸出:

樣本圖 高度意推、寬度、通道 150 300 3
四圖切分珊蟀,求原圖中心位置 75 150
切割為4個(gè)小塊的 W/H/C 信息菊值,并四圖編號(hào):左上=1,右上=2育灸,左下=3腻窒,右下=4
(75, 150, 3) (75, 150, 3) (75, 150, 3) (75, 150, 3)

原圖

切割圖

完成切割后,還需要重組合并4個(gè)圖像磅崭,用于匹配最佳結(jié)果

3.圖像拼接

# 拼接函數(shù)
def merge(sum_rows,sum_cols,channels,p1,p2,p3,p4):
    final_matrix = np.zeros((sum_rows, sum_cols,channels), np.uint8)
    part_rows,part_cols = round(sum_rows/2),round(sum_cols/2)

    final_matrix[0:part_rows, 0:part_cols] = p1
    final_matrix[0:part_rows, part_cols:sum_cols] = p2
    final_matrix[part_rows:sum_rows, 0:part_cols] = p3
    final_matrix[part_rows:sum_rows, part_cols:sum_cols] = p4
    return final_matrix

從編號(hào)上來(lái)看儿子,應(yīng)該將 [1,2,3,4] 還原成 [4,2,3,1] 就是正確的圖,測(cè)試下還原效果

# 還原圖 
f = merge(sum_rows,sum_cols,channels,part4,part2,part3,part1)
show_images([f],'還原圖 [4,2,3,1]')

還原圖 [4,2,3,1]

4.排列組合

已知 python 實(shí)現(xiàn)排列組合非常方便砸喻,測(cè)試代碼如下

import itertools

# 對(duì)應(yīng)拼圖的4個(gè)塊的編號(hào)
puzzle_list = [
    "1:左上","2:右下",
    "3:左下","4:右下"
]

result = itertools.permutations(puzzle_list,4)
cnt=0
for x in result:
    cnt+=1
    print(x)
print('共',cnt,'種組合')

輸出:

('1:左上', '2:右下', '3:左下', '4:右下')
('1:左上', '2:右下', '4:右下', '3:左下')
('1:左上', '3:左下', '2:右下', '4:右下')
('1:左上', '3:左下', '4:右下', '2:右下')
('1:左上', '4:右下', '2:右下', '3:左下')
('1:左上', '4:右下', '3:左下', '2:右下')
('2:右下', '1:左上', '3:左下', '4:右下')
('2:右下', '1:左上', '4:右下', '3:左下')
('2:右下', '3:左下', '1:左上', '4:右下')
('2:右下', '3:左下', '4:右下', '1:左上')
('2:右下', '4:右下', '1:左上', '3:左下')
('2:右下', '4:右下', '3:左下', '1:左上')
('3:左下', '1:左上', '2:右下', '4:右下')
('3:左下', '1:左上', '4:右下', '2:右下')
('3:左下', '2:右下', '1:左上', '4:右下')
('3:左下', '2:右下', '4:右下', '1:左上')
('3:左下', '4:右下', '1:左上', '2:右下')
('3:左下', '4:右下', '2:右下', '1:左上')
('4:右下', '1:左上', '2:右下', '3:左下')
('4:右下', '1:左上', '3:左下', '2:右下')
('4:右下', '2:右下', '1:左上', '3:左下')
('4:右下', '2:右下', '3:左下', '1:左上')
('4:右下', '3:左下', '1:左上', '2:右下')
('4:右下', '3:左下', '2:右下', '1:左上')
共 24 種組合

5.特征提取

采用 merge 函數(shù)柔逼,對(duì)切割的小圖進(jìn)行組合還原后,轉(zhuǎn)換為灰度圖并提取輪廓恩够。

# 還原圖 
f = merge(sum_rows,sum_cols,channels,part1,part2,part3,part4)
show_images([f],'還原圖[1,2,3,4]')
# 灰度
gray = cv2.cvtColor(f, cv2.COLOR_BGRA2GRAY)
show_images([gray],'灰度')
# 提取輪廓
edges = cv2.Canny(gray, 35, 80, apertureSize=3)
show_images([edges],'提取輪廓')

還原圖[1,2,3,4]

灰度

提取輪廓

再測(cè)試一種新的組合卒落,對(duì)比輪廓特征[1,3,2,4]和原始的輪廓特征[4,2,3,1]

f = merge(sum_rows,sum_cols,channels,part1,part3,part2,part4)
gray = cv2.cvtColor(f, cv2.COLOR_BGRA2GRAY)
edges = cv2.Canny(gray, 35, 80, apertureSize=3)
show_images([edges],'提取輪廓')

f = merge(sum_rows,sum_cols,channels,part1,part2,part3,part4)
gray = cv2.cvtColor(f, cv2.COLOR_BGRA2GRAY)
edges = cv2.Canny(gray, 35, 80, apertureSize=3)
show_images([edges],'提取輪廓')

# 正確的
f = merge(sum_rows,sum_cols,channels,part4,part2,part3,part1)
gray = cv2.cvtColor(f, cv2.COLOR_BGRA2GRAY)
edges = cv2.Canny(gray, 35, 80, apertureSize=3)
show_images([edges],'正確的-提取輪廓')

提取輪廓

提取輪廓

正確的-提取輪廓

通過(guò)提取輪廓,可以看到拼接結(jié)果的明顯的線條蜂桶,錯(cuò)誤的圖至少存在一條x軸或y軸的線儡毕,而拼接成功的基本沒(méi)有(線段位置或長(zhǎng)度及線條數(shù)量可以決定正確率,需要多調(diào)整參數(shù)并篩選)扑媚。

這是因?yàn)樵瓐D有明顯的過(guò)渡色腰湾,它是為了用戶體驗(yàn)而設(shè)計(jì),方便人們使用它的時(shí)候疆股,能夠‘容易’的區(qū)分费坊,并找出正確的拼圖位置。

f = merge(sum_rows,sum_cols,channels,part1,part2,part3,part4)
show_images([f],'背景漸變色')
show_images([part3,part2,part1,part4],'切割后')
f = merge(sum_rows,sum_cols,channels,part1,part2,part3,part4)
lf = f.copy()
cv2.line(lf, (0, 75), (300, 75), (0, 0, 255), 2)
cv2.line(lf, (150, 0), (150, 150), (0, 0, 255), 2)
show_images([lf],'亂序旬痹,漸變色成為了‘十字’特征線')

背景漸變色

切割后

亂序附井,漸變色成為了‘十字’特征線

6.特征匹配

特征已知后讨越,現(xiàn)在剩下的就是對(duì)特征進(jìn)行檢測(cè),可以計(jì)算 x/2,y/2 十字架的色差永毅,也可以用 opencv 的直線提取把跨,測(cè)試代碼如下:

f = merge(sum_rows,sum_cols,channels,part1,part2,part3,part4)
gray = cv2.cvtColor(f, cv2.COLOR_BGRA2GRAY)
edges = cv2.Canny(gray, 35, 80, apertureSize=3)
show_images([edges],'提取輪廓')

lines = cv2.HoughLinesP(edges,0.01,np.pi/360,60,minLineLength=50,maxLineGap=10)
if lines is None:
    print('沒(méi)找到線條')
else:
    lf = f.copy()
    for line in lines:
        x1, y1, x2, y2 = line[0]
        cv2.line(lf, (x1, y1), (x2, y2), (0, 0, 255), 2)
    show_images([lf])

提取輪廓

嘗試正確的組合 [4,2,3,1]

f = merge(sum_rows,sum_cols,channels,part4,part2,part3,part1)
gray = cv2.cvtColor(f, cv2.COLOR_BGRA2GRAY)
edges = cv2.Canny(gray, 35, 80, apertureSize=3)
show_images([edges],'提取輪廓')

lines = cv2.HoughLinesP(edges,0.01,np.pi/360,60,minLineLength=50,maxLineGap=10)
if lines is None:
    print('沒(méi)找到線條')
else:
    lf = f.copy()
    for line in lines:
        x1, y1, x2, y2 = line[0]
        cv2.line(lf, (x1, y1), (x2, y2), (0, 0, 255), 2)
    show_images([lf])

提取輪廓

沒(méi)找到線條

7.匹配過(guò)程

import itertools

print('原圖順序')
print(1,2)
print(3,4)
show_images([img])

# 按編號(hào),將切割的圖放入list做排列組合
list1 = [
    [1,part1],
    [2,part2],
    [3,part3],
    [4,part4]
]

result = itertools.permutations(list1,4)
idx =1
finded = False
finalResult = []
for x in result:
    # 排列組合合并圖像
    f = merge(sum_rows,sum_cols,channels,x[0][1],x[1][1],x[2][1],x[3][1])
    # 圖像特征提取
    gray = cv2.cvtColor(f, cv2.COLOR_BGRA2GRAY)
    edges = cv2.Canny(gray, 35, 80, apertureSize=3)
    # 直線匹配
    lines = cv2.HoughLinesP(edges,0.01,np.pi/360,60,minLineLength=50,maxLineGap=10)
    if lines is None:
        print('還原圖像')
        show_images([f])
        show_images([gray])
        show_images([edges])
        print('正確順序')
        print(x[0][0],x[1][0])
        print(x[2][0],x[3][0])
        print('完成!!')
        finded = True
        finalResult =[x[0][0],x[1][0],x[2][0],x[3][0]] #獲取最終排列正確的結(jié)果
        break
    else:
        print(idx, '排列:' , x[0][0],x[1][0],x[2][0],x[3][0] , '線:', len(lines))
        lf = f.copy()
        for line in lines:
            x1, y1, x2, y2 = line[0]
            cv2.line(lf, (x1, y1), (x2, y2), (0, 0, 255), 2)
#         show_images([lf])
        pass
    idx+=1

print('測(cè)試次數(shù)',idx,'最終狀態(tài)',finded,finalResult)

輸出:

原圖順序
1 2
3 4
1 排列: 1 2 3 4 線: 4
2 排列: 1 2 4 3 線: 5
3 排列: 1 3 2 4 線: 4
4 排列: 1 3 4 2 線: 2
5 排列: 1 4 2 3 線: 3
6 排列: 1 4 3 2 線: 4
7 排列: 2 1 3 4 線: 3
8 排列: 2 1 4 3 線: 5
9 排列: 2 3 1 4 線: 3
10 排列: 2 3 4 1 線: 3
11 排列: 2 4 1 3 線: 1
12 排列: 2 4 3 1 線: 1
13 排列: 3 1 2 4 線: 2
14 排列: 3 1 4 2 線: 2
15 排列: 3 2 1 4 線: 3
16 排列: 3 2 4 1 線: 3
17 排列: 3 4 1 2 線: 5
18 排列: 3 4 2 1 線: 3
19 排列: 4 1 2 3 線: 4
20 排列: 4 1 3 2 線: 3
21 排列: 4 2 1 3 線: 2

還原圖像

正確順序
4 2
3 1
完成!
測(cè)試次數(shù) 22 最終狀態(tài) True [4, 2, 3, 1]

8.提取結(jié)果

再看看如何這種拼圖沼死,如果要交換位置的組合有12種

list1 = [1,2,3,4]

result = itertools.permutations(list1,2)
idx=0
for x in result:
    idx+=1
    print(idx,x)

輸出:

1 (1, 2)
2 (1, 3)
3 (1, 4)
4 (2, 1)
5 (2, 3)
6 (2, 4)
7 (3, 1)
8 (3, 2)
9 (3, 4)
10 (4, 1)
11 (4, 2)
12 (4, 3)

交換函數(shù)

#交換函數(shù)
def change_check(a,b):
    diffs = []
    if len(a)!=len(b):
        return diffs

    for i in range(len(a)):
        if a[i]!=b[I]:
            diffs.append(b[I])
    return diffs

ab = change_check([1,2,3,4],finalResult)
print('原始',[1,2,3,4])
print('最終',finalResult)
print('要交換的位置',ab)

輸出:

原始 [1, 2, 3, 4]
最終 [4, 2, 3, 1]
要交換的位置 [4, 1]

將‘交換的位置’換算成小圖中心的偏移坐標(biāo)着逐,采用查表法

#大圖尺寸
pwidth = 150 
pheight = 75 
#小圖xy中心點(diǎn) = 大圖wh 1/4
px = round(pwidth/2)
py = round(pheight/2)
#創(chuàng)建坐標(biāo)表
offset_points = [
    [px,py],[px+pwidth,py],
    [px,py+pheight],[px+pwidth,py+pheight]
]
print(offset_points)
print(ab)
#通過(guò)結(jié)果作為索引,拿到坐標(biāo)表索引的坐標(biāo)
drag_start = offset_points[ ab[0] -1 ]
drag_end = offset_points[ ab[1] -1 ]

print('起點(diǎn)偏移坐標(biāo)',drag_start,'終點(diǎn)偏移坐標(biāo)',drag_end)

輸出:

[[75, 38], [225, 38], [75, 113], [225, 113]]
[4, 1]
起點(diǎn)偏移坐標(biāo) [225, 113] 終點(diǎn)偏移坐標(biāo) [75, 38]

9.模擬操作

至此意蛀,已經(jīng)完成了拼圖還原的分析所有過(guò)程耸别,下面采用另一種簡(jiǎn)單的方法,move_to_element 方法县钥,內(nèi)置的拖動(dòng) dom-a 到 dom-b 位置秀姐,測(cè)試下結(jié)果

# 模擬聚焦按鈕,讓拼圖顯示出來(lái)
onebtn = browser2.find_element_by_css_selector('#dx_captcha_oneclick_bar-logo_2 > span')
ActionChains(browser2).move_to_element(onebtn).perform() 
time.sleep(1)

獲取最終結(jié)果

ab = change_check([1,2,3,4],finalResult)
print(ab)

輸出

[4, 1]

找到網(wǎng)頁(yè)拼圖的dom元素魁蒜,存儲(chǔ)下來(lái)用于操作并交換拼圖

d1 = browser2.find_element_by_css_selector('#dx_captcha_jigsaw_fragment-top-left_3 > div')
d2 = browser2.find_element_by_css_selector('#dx_captcha_jigsaw_fragment-top-right_3 > div')
d3 = browser2.find_element_by_css_selector('#dx_captcha_jigsaw_fragment-bottom-left_3 > div')
d4 = browser2.find_element_by_css_selector('#dx_captcha_jigsaw_fragment-bottom-right_3 > div')
drag_elements = [d1,d2,d3,d4]

找出要拖動(dòng)的2個(gè)dom囊扳,并交付給 webdriver

drag_start = drag_elements[ ab[0] -1 ]
drag_end = drag_elements[ ab[1] -1 ]
print('drag_start',drag_start, 'drag_end',drag_end)

輸出

drag_start <selenium.webdriver.remote.webelement.WebElement (session="1d7d691bd509cd03cd8b1483da2056ea", element="8439005e-eb70-4b02-856e-eebbe2526d6d")> 
drag_end <selenium.webdriver.remote.webelement.WebElement (session="1d7d691bd509cd03cd8b1483da2056ea", element="f9239df5-9aa3-43ae-a6af-afacf81eb670")>

執(zhí)行動(dòng)作

ActionChains(browser2).drag_and_drop(drag_start,drag_end).perform()
# browser2.close()

簡(jiǎn)單拖一下,目標(biāo)網(wǎng)站認(rèn)可了兜看,但它判定是有問(wèn)題的锥咸,又彈出一種新的驗(yàn)證碼出來(lái),看來(lái)僅僅能夠識(shí)別還原正確拼圖還只是開(kāi)端细移,如何偽造一個(gè)讓其認(rèn)可的運(yùn)行環(huán)境搏予,又是一個(gè)新的技術(shù)研究領(lǐng)域,值得與各位共同學(xué)習(xí)與分享交流弧轧。

六雪侥、終

邊學(xué)邊做,如有錯(cuò)誤之處敬請(qǐng)指出精绎,謝謝速缨!

項(xiàng)目地址:https://github.com/suifei/puzzle-captcha

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市代乃,隨后出現(xiàn)的幾起案子旬牲,更是在濱河造成了極大的恐慌,老刑警劉巖搁吓,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件原茅,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡堕仔,警方通過(guò)查閱死者的電腦和手機(jī)擂橘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)摩骨,“玉大人通贞,你說(shuō)我怎么就攤上這事朗若。” “怎么了滑频?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵捡偏,是天一觀的道長(zhǎng)唤冈。 經(jīng)常有香客問(wèn)我峡迷,道長(zhǎng),這世上最難降的妖魔是什么你虹? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任绘搞,我火速辦了婚禮,結(jié)果婚禮上傅物,老公的妹妹穿的比我還像新娘夯辖。我一直安慰自己,他們只是感情好董饰,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布蒿褂。 她就那樣靜靜地躺著,像睡著了一般卒暂。 火紅的嫁衣襯著肌膚如雪啄栓。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天也祠,我揣著相機(jī)與錄音昙楚,去河邊找鬼。 笑死诈嘿,一個(gè)胖子當(dāng)著我的面吹牛堪旧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播奖亚,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼淳梦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了昔字?” 一聲冷哼從身側(cè)響起爆袍,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎李滴,沒(méi)想到半個(gè)月后螃宙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡所坯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年谆扎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片芹助。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡堂湖,死狀恐怖闲先,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情无蜂,我是刑警寧澤伺糠,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站斥季,受9級(jí)特大地震影響训桶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜酣倾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一舵揭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧躁锡,春花似錦午绳、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至杠输,卻和暖如春赎败,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抬伺。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工螟够, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人峡钓。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓妓笙,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親能岩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子寞宫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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