Atlassian系列软件破解研究记录

Atlassian系列软件破解研究记录

声明

仅供个人学习、研究使用,请勿用于商业用途。

基于的版本

产品 版本
Confluence 6.0.6
Jira Software 7.3.3
Bitbucket 4.14.2
Bamboo 5.15.3
Crucible & FishEye 4.3.1

License 明文内容

Confluence

Description=Confluence (Data Center)
ServerID=BSVW-4XDC-RWIW-M083
Organisation=Your Organisation
ContactEMail=example@example.com
LicenseTypeName=COMMERCIAL
NumberOfUsers=-1
Subscription=true
Evaluation=false
PurchaseDate=2017-03-14
CreationDate=2017-03-14
LicenseExpiryDate=unlimited
MaintenanceExpiryDate=253402257599855
LicenseID=LIDSEN-L9418768
SEN=SEN-L9418768
licenseVersion=2

conf.LicenseEdition=ENTERPRISE
conf.DataCenter=false
conf.active=true
conf.NumberOfUsers=-1
conf.Starter=false
conf.LicenseTypeName=COMMERCIAL

注意:

  1. conf.DataCenter=trueLicenseExpiryDate不能设置为unlimited
    参见以下LicenseValidator
    confluence-${version}.jar com.atlassian.confluence.license.validator.DataCenterLicenseExpiryValidator
  2. conf.DataCenter=true 只能用于生产环境,使用这种License,Confluence不支持再使用内置的数据库,需要配置受支持的其他数据库。

Jira Software

Description=JIRA Software (Data Center)
ServerID=BSVW-4XDC-RWIW-M083
Organisation=Your Organisation
ContactEMail=example@example.com
LicenseTypeName=COMMERCIAL
NumberOfUsers=-1
Subscription=true
Evaluation=false
PurchaseDate=2017-03-15
CreationDate=2017-03-15
LicenseExpiryDate=253402257599855
MaintenanceExpiryDate=253402257599855
LicenseID=LIDSEN-L9423264
SEN=SEN-L9423264
licenseVersion=2

greenhopper.LicenseEdition=ENTERPRISE
jira.NumberOfUsers=-1
jira.product.jira-software.active=true
jira.product.jira-software.DataCenter=false
jira.LicenseEdition=ENTERPRISE
greenhopper.LicenseTypeName=COMMERCIAL
jira.product.jira-software.NumberOfUsers=-1
jira.DataCenter=false
jira.product.jira-software.Starter=false
greenhopper.enterprise=true
jira.active=true
jira.LicenseTypeName=COMMERCIAL
greenhopper.active=true

Bitbucket (原 Stash)

Description=Bitbucket (Data Center)
ServerID=BSVW-4XDC-RWIW-M083
Organisation=Your Organisation
ContactEMail=example@example.com
LicenseTypeName=COMMERCIAL
NumberOfUsers=-1
Subscription=true
Evaluation=false
PurchaseDate=2017-03-14
CreationDate=2017-03-14
LicenseExpiryDate=unlimited
MaintenanceExpiryDate=253402257599855
LicenseID=LIDSEN-L9418768
SEN=SEN-L9418768
licenseVersion=2

stash.LicenseTypeName=COMMERCIAL
stash.DataCenter=false
stash.active=true
stash.NumberOfUsers=-1
stash.Starter=false

Bamboo

Description=Bamboo (Server) unlimited Remote Agents
ServerID=BSVW-4XDC-RWIW-M083
Organisation=Your Organisation
ContactEMail=example@example.com
LicenseTypeName=COMMERCIAL
NumberOfUsers=-1
Subscription=true
Evaluation=false
PurchaseDate=2017-03-14
CreationDate=2017-03-14
LicenseExpiryDate=unlimited
MaintenanceExpiryDate=253402257599855
LicenseID=LIDSEN-L9418768
SEN=SEN-L9418768
licenseVersion=2

bamboo.LicenseEdition=ENTERPRISE
bamboo.NumberOfBambooLocalAgents=-1
bamboo.active=true
bamboo.NumberOfBambooRemoteAgents=-1
bamboo.NumberOfBambooPlans=-1
bamboo.LicenseTypeName=COMMERCIAL

Crucible & FishEye

Description=Crucible (Server)
ServerID=B164-53DN-93PE-5MRN
Organisation=Your Organisation
ContactEMail=example@example.com
LicenseTypeName=COMMERCIAL
NumberOfUsers=-1
Subscription=true
Evaluation=false
PurchaseDate=2017-03-14
CreationDate=2017-03-14
LicenseExpiryDate=unlimited
MaintenanceExpiryDate=4102401599852
LicenseID=LIDSEN-L9418768
SEN=SEN-L9418768
licenseVersion=2

crucible.LicenseTypeName=COMMERCIAL
crucible.Starter=false
crucible.NumberOfUsers=-1
crucible.active=true
Description=FishEye (Server)
ServerID=B164-53DN-93PE-5MRN
Organisation=Your Organisation
ContactEMail=example@example.com
LicenseTypeName=COMMERCIAL
NumberOfUsers=-1
Subscription=true
Evaluation=false
PurchaseDate=2017-03-14
CreationDate=2017-03-14
LicenseExpiryDate=unlimited
MaintenanceExpiryDate=4102401599852
LicenseID=LIDSEN-L9418768
SEN=SEN-L9418768
licenseVersion=2

fisheye.active=true
fisheye.Starter=false
fisheye.LicenseTypeName=COMMERCIAL
fisheye.NumberOfUsers=-1

License 结构

License是一个basee64字符串,由三部分组成

第一部分:License
第二部分:License版本号 固定值 X02
第三部分:第一部分长度 31进制形式

上面的第一部分base64解码后,又由以下四个部分组成

第一部分:第二部加第三部分的分长度 4个字节
第二部分:License前缀 当前为5个字节
第三部分:zip压缩后的License内容
第四部分:第二部加第三部分的签名

签名算法为 SHA1withDSA

代码 com.atlassian.extras.decoder.v2.Version2LicenseDecoder#checkAndGetLicenseText(String) 方法中

com.atlassian.extras.decoder.v2.Version2LicenseDecoder所在包

产品 所在包
Confluence $INSTALL_DIR/confluence/WEB-INF/lib/atlassian-extras-decoder-v2-3.2.jar
Jira Software $INSTALL_DIR/atlassian-jira/WEB-INF/lib/atlassian-extras-3.2.jar
Bitbucket $INSTALL_DIR/atlassian-bitbucket/WEB-INF/lib/atlassian-extras-decoder-v2-3.3.0.jar
Bamboo $INSTALL_DIR/atlassian-bamboo/WEB-INF/lib/atlassian-extras-decoder-v2-3.3.0.jar
Crucible & FishEye $INSTALL_DIR/lib/atlassian-extras-2.5.jar

破解思路

  1. com.atlassian.extras.decoder.v2.Version2LicenseDecoder中的
    公钥替换成自己的
  2. 根据License的结构,使用自己的私钥生成License

成果

破解成功!

替换公钥

反编 --> 替换公钥 --> 编译 --> 替换原jar包的class文件

生成 License 代码

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Scanner;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;

/**
 * @author Shauway <shauway@qq.com>
 */
public class AtlassianLicenseGenerator {
    public static final String CONFLUENCE_SERVER_LICENSE_DESC = "Confluence (Server)";
    public static final String CONFLUENCE_DATA_CENTER_LICENSE_DESC = "Confluence (Data Center)";
    public static final String JIRA_SOFTWARE_SERVER_LICENSE_DESC = "Jira Software (Server)";
    public static final String JIRA_SOFTWARE_DATA_CENTER_LICENSE_DESC = "Jira Software (Data Center)";
    public static final String BITBUCKET_SERVER_LICENSE_DESC = "Bitbucket (Server)";
    public static final String BITBUCKET_DATA_CENTER_LICENSE_DESC = "Bitbucket (Data Center)";
    public static final String BAMBOO_SERVER_LICENSE_DESC = "Bamboo (Server) Unlimited Remote Agents";
    public static final String CRUCIBLE_SERVER_LICENSE_DESC = "Crucible (Server)";
    public static final String FISH_EYE_SERVER_LICENSE_DESC = "FishEye (Server)";
    static String COMMON_LICENSE_CONTENT = "Description=$$licenseDesc$$\n" +
            "ServerID=$$serverid$$\n" +
            "Organisation=$$org$$\n" +
            "ContactEMail=$$email$$\n" +
            "LicenseTypeName=COMMERCIAL\n" +
            "NumberOfUsers=-1\n" +
            "Subscription=true\n" +
            "Evaluation=false\n" +
            "PurchaseDate=2017-03-14\n" +
            "CreationDate=2017-03-14\n" +
            "LicenseExpiryDate=$$license_expiry_date$$\n" +
            "MaintenanceExpiryDate=$$maintenance_expiry_date$$\n" +
            "LicenseID=LIDSEN-L9418768\n" +
            "SEN=SEN-L9418768\n" +
            "licenseVersion=2\n";
    static String CONFLUENCE_SPECIAL_LICENSE_CONTENT = "conf.LicenseEdition=ENTERPRISE\n" +
            "conf.DataCenter=$$data_center$$\n" +
            "conf.active=true\n" +
            "conf.NumberOfUsers=-1\n" +
            "conf.Starter=false\n" +
            "conf.LicenseTypeName=COMMERCIAL";
    static String JIRA_SPECIAL_LICENSE_CONTENT = "greenhopper.LicenseEdition=ENTERPRISE\n" +
            "jira.NumberOfUsers=-1\n" +
            "jira.product.jira-software.active=true\n" +
            "jira.product.jira-software.DataCenter=false\n" +
            "jira.LicenseEdition=ENTERPRISE\n" +
            "greenhopper.LicenseTypeName=COMMERCIAL\n" +
            "jira.product.jira-software.NumberOfUsers=-1\n" +
            "jira.DataCenter=$$data_center$$\n" +
            "jira.product.jira-software.Starter=false\n" +
            "greenhopper.enterprise=true\n" +
            "jira.active=true\n" +
            "jira.LicenseTypeName=COMMERCIAL\n" +
            "greenhopper.active=true";
    static String BITBUCKET_SPECIAL_LICENSE_CONTENT = "stash.LicenseTypeName=COMMERCIAL\n" +
            "stash.DataCenter=$$data_center$$\n" +
            "stash.active=true\n" +
            "stash.NumberOfUsers=-1\n" +
            "stash.Starter=false";
    static String BAMBOO_SPECIAL_LICENSE_CONTENT = "bamboo.LicenseEdition=ENTERPRISE\n" +
            "bamboo.NumberOfBambooLocalAgents=-1\n" +
            "bamboo.active=true\n" +
            "bamboo.NumberOfBambooRemoteAgents=-1\n" +
            "bamboo.NumberOfBambooPlans=-1\n" +
            "bamboo.LicenseTypeName=COMMERCIAL";
    static String CRUCIBLE_SPECIAL_LICENSE_CONTENT = "crucible.LicenseTypeName=COMMERCIAL\n" +
            "crucible.Starter=false\n" +
            "crucible.NumberOfUsers=-1\n" +
            "crucible.active=true";
    static String FISH_SPECIAL_LICENSE_CONTENT = "fisheye.active=true\n" +
            "fisheye.Starter=false\n" +
            "fisheye.LicenseTypeName=COMMERCIAL\n" +
            "fisheye.NumberOfUsers=-1";

    static String LINE_SEPARATOR = System.getProperty("line.separator");
    static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) throws Exception {
        StringBuffer prompt = new StringBuffer();
        prompt.append("Select license type:").append(LINE_SEPARATOR);
        prompt.append("\t11: ").append(CONFLUENCE_SERVER_LICENSE_DESC).append(LINE_SEPARATOR);
        prompt.append("\t12: ").append(CONFLUENCE_DATA_CENTER_LICENSE_DESC).append(LINE_SEPARATOR);
        prompt.append("\t21: ").append(JIRA_SOFTWARE_SERVER_LICENSE_DESC).append(LINE_SEPARATOR);
        prompt.append("\t22: ").append(JIRA_SOFTWARE_DATA_CENTER_LICENSE_DESC).append(LINE_SEPARATOR);
        prompt.append("\t31: ").append(BITBUCKET_SERVER_LICENSE_DESC).append(LINE_SEPARATOR);
        prompt.append("\t32: ").append(BITBUCKET_DATA_CENTER_LICENSE_DESC).append(LINE_SEPARATOR);
        prompt.append("\t4: ").append(BAMBOO_SERVER_LICENSE_DESC).append(LINE_SEPARATOR);
        prompt.append("\t5: ").append(CRUCIBLE_SERVER_LICENSE_DESC).append(LINE_SEPARATOR);
        prompt.append("\t6: ").append(FISH_EYE_SERVER_LICENSE_DESC).append(LINE_SEPARATOR);
        System.out.print(prompt);
        System.out.print(">> Input selected license type code: ");
        int licenseTypeCode = scanner.nextInt();
        switch (licenseTypeCode) {
            case 11:
                COMMON_LICENSE_CONTENT = COMMON_LICENSE_CONTENT.replace("$$licenseDesc$$", CONFLUENCE_SERVER_LICENSE_DESC)
                        .replace("$$license_expiry_date$$", "unlimited")
                        .replace("$$maintenance_expiry_date$$", "253402257599855");
                CONFLUENCE_SPECIAL_LICENSE_CONTENT = CONFLUENCE_SPECIAL_LICENSE_CONTENT.replace("$$data_center$$", "false");
                break;
            case 12:
                COMMON_LICENSE_CONTENT = COMMON_LICENSE_CONTENT.replace("$$licenseDesc$$", CONFLUENCE_DATA_CENTER_LICENSE_DESC)
                        .replace("$$license_expiry_date$$", "253402257599855")
                        .replace("$$maintenance_expiry_date$$", "253402257599855");
                CONFLUENCE_SPECIAL_LICENSE_CONTENT = CONFLUENCE_SPECIAL_LICENSE_CONTENT.replace("$$data_center$$", "true");
                break;
            case 21:
                COMMON_LICENSE_CONTENT = COMMON_LICENSE_CONTENT.replace("$$licenseDesc$$", JIRA_SOFTWARE_SERVER_LICENSE_DESC)
                        .replace("$$license_expiry_date$$", "unlimited")
                        .replace("$$maintenance_expiry_date$$", "253402257599855");
                JIRA_SPECIAL_LICENSE_CONTENT = JIRA_SPECIAL_LICENSE_CONTENT.replace("$$data_center$$", "false");
                break;
            case 22:
                COMMON_LICENSE_CONTENT = COMMON_LICENSE_CONTENT.replace("$$licenseDesc$$", JIRA_SOFTWARE_DATA_CENTER_LICENSE_DESC)
                        .replace("$$license_expiry_date$$", "253402257599855")
                        .replace("$$maintenance_expiry_date$$", "253402257599855");
                JIRA_SPECIAL_LICENSE_CONTENT = JIRA_SPECIAL_LICENSE_CONTENT.replace("$$data_center$$", "true");
                break;
            case 31:
                COMMON_LICENSE_CONTENT = COMMON_LICENSE_CONTENT.replace("$$licenseDesc$$", BITBUCKET_SERVER_LICENSE_DESC)
                        .replace("$$license_expiry_date$$", "unlimited")
                        .replace("$$maintenance_expiry_date$$", "253402257599855");
                BITBUCKET_SPECIAL_LICENSE_CONTENT = BITBUCKET_SPECIAL_LICENSE_CONTENT.replace("$$data_center$$", "false");
                break;
            case 32:
                COMMON_LICENSE_CONTENT = COMMON_LICENSE_CONTENT.replace("$$licenseDesc$$", BITBUCKET_DATA_CENTER_LICENSE_DESC)
                        .replace("$$license_expiry_date$$", "253402257599855")
                        .replace("$$maintenance_expiry_date$$", "253402257599855");
                BITBUCKET_SPECIAL_LICENSE_CONTENT = BITBUCKET_SPECIAL_LICENSE_CONTENT.replace("$$data_center$$", "true");
                break;
            case 4:
                COMMON_LICENSE_CONTENT = COMMON_LICENSE_CONTENT.replace("$$licenseDesc$$", BAMBOO_SERVER_LICENSE_DESC)
                        .replace("$$license_expiry_date$$", "unlimited")
                        .replace("$$maintenance_expiry_date$$", "4102401599852");
                break;
            case 5:
                COMMON_LICENSE_CONTENT = COMMON_LICENSE_CONTENT.replace("$$licenseDesc$$", CRUCIBLE_SERVER_LICENSE_DESC)
                        .replace("$$license_expiry_date$$", "unlimited")
                        .replace("$$maintenance_expiry_date$$", "4102401599852");
                break;
            case 6:
                COMMON_LICENSE_CONTENT = COMMON_LICENSE_CONTENT.replace("$$licenseDesc$$", FISH_EYE_SERVER_LICENSE_DESC)
                        .replace("$$license_expiry_date$$", "unlimited")
                        .replace("$$maintenance_expiry_date$$", "4102401599852");
                break;
            default:
                System.out.println("Invalid license type code!");
                System.exit(1);
        }
        System.out.print(">> Input your server id: ");
        String serverId = scanner.next();
        System.out.print(">> Input your organisation name: ");
        String organisation = scanner.next();
        System.out.print(">> Input your email address: ");
        String email = scanner.next();
        COMMON_LICENSE_CONTENT = COMMON_LICENSE_CONTENT.replace("$$serverid$$", serverId)
                .replace("$$org$$", organisation).replace("$$email$$", email);
        String licenseContent = null;
        switch (licenseTypeCode) {
            case 11:
            case 12:
                licenseContent = COMMON_LICENSE_CONTENT + CONFLUENCE_SPECIAL_LICENSE_CONTENT;
                break;
            case 21:
            case 22:
                licenseContent = COMMON_LICENSE_CONTENT + JIRA_SPECIAL_LICENSE_CONTENT;
                break;
            case 31:
            case 32:
                licenseContent = COMMON_LICENSE_CONTENT + BITBUCKET_SPECIAL_LICENSE_CONTENT;
                break;
            case 4:
                licenseContent = COMMON_LICENSE_CONTENT + BAMBOO_SPECIAL_LICENSE_CONTENT;
                break;
            case 5:
                licenseContent = COMMON_LICENSE_CONTENT + CRUCIBLE_SPECIAL_LICENSE_CONTENT;
                break;
            case 6:
                licenseContent = COMMON_LICENSE_CONTENT + FISH_SPECIAL_LICENSE_CONTENT;
                break;
        }
        System.out.println();
        System.out.println("Your license content. Enjoy it!");
        System.out.println();
        System.out.println(getLicense(licenseContent));
        System.out.println();
        System.out.println(licenseContent);
    }

    static PublicKey publicKey;
    static PrivateKey privateKey;
    static byte[] licenseTextPrefix = {13, 14, 12, 10, 15};

    static {
        try {
            KeyFactory keyFactory = KeyFactory.getInstance("DSA");
            publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(Base64.getUrlDecoder().decode("MIIBuDCCASwGByqGSM44BAEwggEfAoGBAP1_U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq_xfW6MPbLm1Vs14E7gB00b_JmYLdrmVClpJ-f6AR7ECLCT7up1_63xhv4O1fnxqimFQ8E-4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC_BYHPUCgYEA9-GghdabPd7LvKtcNrhXuXmUr7v6OuqC-VdMCz0HgmdRWVeOutRZT-ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN_C_ohNWLx-2J6ASQ7zKTxvqhRkImog9_hWuWfBpKLZl6Ae1UlZAFMO_7PSSoDgYUAAoGBAOshUqTDMJgJhrrooXl9ajUjDyunW8FSX1IjOOyNRwd0TEwtzfZzzAzUsGm4bPYjIHQpe1ovONVVUpEzYJGJMxVXbbBHQYMbevdvSUdq90LLWXhgwwlXRAwqPq9S0YZP7r9uisPruk59LVj-D-L_GVacH01LlWkm74ya1CusMxDc")));
            privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode("MIIBTAIBADCCASwGByqGSM44BAEwggEfAoGBAP1_U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq_xfW6MPbLm1Vs14E7gB00b_JmYLdrmVClpJ-f6AR7ECLCT7up1_63xhv4O1fnxqimFQ8E-4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC_BYHPUCgYEA9-GghdabPd7LvKtcNrhXuXmUr7v6OuqC-VdMCz0HgmdRWVeOutRZT-ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN_C_ohNWLx-2J6ASQ7zKTxvqhRkImog9_hWuWfBpKLZl6Ae1UlZAFMO_7PSSoEFwIVAIPdS-RMIsqurIg1ONM3UjobnZiz")));
        } catch (Exception e) {
        }
    }

    static String getLicense(String licenseContent) throws Exception {
        byte[] licenseTextBytes = licenseContent.getBytes("UTF-8"); // 未压缩

        Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION);
        ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
        DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(baos2, deflater);
        deflaterOutputStream.write(licenseTextBytes);
        deflaterOutputStream.close();
        byte[] licenseTextBytesZiped = baos2.toByteArray(); // 已压缩

        Signature signature = Signature.getInstance("SHA1withDSA");
        signature.initSign(privateKey);
        signature.update(licenseTextPrefix);
        signature.update(licenseTextBytesZiped);
        byte[] sign = signature.sign();

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(baos);
        dos.writeInt(licenseTextBytesZiped.length + licenseTextPrefix.length);
        dos.write(licenseTextPrefix);
        dos.write(licenseTextBytesZiped);
        dos.write(sign);

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

推荐阅读更多精彩内容