1.3Linux基礎(chǔ)

目錄

常用基礎(chǔ)命令

ls                  用來顯示目標列表

cd [path]           用來切換工作目錄

pwd                 以絕對路徑的方式顯示用戶當前工作目錄

man [command]       查看Linux中的指令幫助、配置文件幫助和編程幫助等信息

apropos [whatever]  在一些特定的包含系統(tǒng)命令的簡短描述的數(shù)據(jù)庫文件里查找關(guān)鍵字

echo [string]       打印一行文本,參數(shù)“-e”可激活轉(zhuǎn)義字符

cat [file]          連接文件并打印到標準輸出設(shè)備上

less [file]         允許用戶向前或向后瀏覽文字檔案的內(nèi)容

mv [file1] [file2]  用來對文件或目錄重新命名若河,或者將文件從一個目錄移到另一個目錄中

cp [file1] [file2]  用來將一個或多個源文件或者目錄復制到指定的目的文件或目錄

rm [file]           可以刪除一個目錄中的一個或多個文件或目錄,也可以將某個目錄及其下屬的所有文件及其子目錄均刪除掉

ps                  用于報告當前系統(tǒng)的進程狀態(tài)

top                 實時查看系統(tǒng)的整體運行情況

kill                殺死一個進程

ifconfig            查看或設(shè)置網(wǎng)絡(luò)設(shè)備

ping                查看網(wǎng)絡(luò)上的主機是否工作

netstat             顯示網(wǎng)絡(luò)連接挥吵、路由表和網(wǎng)絡(luò)接口信息

nc(netcat)          建立 TCP 和 UDP 連接并監(jiān)聽

su                  切換當前用戶身份到其他用戶身份

touch [file]        創(chuàng)建新的空文件

mkdir [dir]         創(chuàng)建目錄

chmod               變更文件或目錄的權(quán)限

chown               變更某個文件或目錄的所有者和所屬組

nano / vim / emacs  字符終端的文本編輯器

exit                退出 shell
管道命令符 "|"       將一個命令的標準輸出作為另一個命令的標準輸入

使用變量:

var=value         給變量var賦值value

$var, ${var}      取變量的值

`cmd`, $(cmd)     代換標準輸出

'string'          非替換字符串

"string"          可替換字符串
$ var="test";
$ echo $var
test
$ echo 'This is a $var';
This is a $var
$ echo "This is a $var";
This is a test

$ echo `date`;
2017年 11月 06日 星期一 14:40:07 CST
$ $(bash)

$ echo $0
/bin/bash
$ $($0)

Bash 快捷鍵

Up(Down)          上(下)一條指令

Ctrl + c          終止當前進程

Ctrl + z          掛起當前進程,使用“fg”可喚醒

Ctrl + d          刪除光標處的字符

Ctrl + l          清屏

Ctrl + a          移動到命令行首

Ctrl + e          移動到命令行尾

Ctrl + b          按單詞后移(向左)

Ctrl + f          按單詞前移(向右)

Ctrl + Shift + c  復制

Ctrl + Shift + v  粘貼

更多細節(jié)請查看:Bash Keyboard Shortcuts

根目錄結(jié)構(gòu)

$ uname -a
Linux manjaro 4.11.5-1-ARCH #1 SMP PREEMPT Wed Jun 14 16:19:27 CEST 2017 x86_64 GNU/Linux
$ ls -al /
drwxr-xr-x  17 root root  4096 Jun 28 20:17 .
drwxr-xr-x  17 root root  4096 Jun 28 20:17 ..
lrwxrwxrwx   1 root root     7 Jun 21 22:44 bin -> usr/bin
drwxr-xr-x   4 root root  4096 Aug 10 22:50 boot
drwxr-xr-x  20 root root  3140 Aug 11 11:43 dev
drwxr-xr-x 101 root root  4096 Aug 14 13:54 etc
drwxr-xr-x   3 root root  4096 Apr  8 19:59 home
lrwxrwxrwx   1 root root     7 Jun 21 22:44 lib -> usr/lib
lrwxrwxrwx   1 root root     7 Jun 21 22:44 lib64 -> usr/lib
drwx------   2 root root 16384 Apr  8 19:55 lost+found
drwxr-xr-x   2 root root  4096 Oct  1  2015 mnt
drwxr-xr-x  15 root root  4096 Jul 15 20:10 opt
dr-xr-xr-x 267 root root     0 Aug  3 09:41 proc
drwxr-x---   9 root root  4096 Jul 22 22:59 root
drwxr-xr-x  26 root root   660 Aug 14 21:08 run
lrwxrwxrwx   1 root root     7 Jun 21 22:44 sbin -> usr/bin
drwxr-xr-x   4 root root  4096 May 28 22:07 srv
dr-xr-xr-x  13 root root     0 Aug  3 09:41 sys
drwxrwxrwt  36 root root  1060 Aug 14 21:27 tmp
drwxr-xr-x  11 root root  4096 Aug 14 13:54 usr
drwxr-xr-x  12 root root  4096 Jun 28 20:17 var

由于不同的發(fā)行版會有略微的不同,我們這里使用的是基于 Arch 的發(fā)行版 Manjaro,以上就是根目錄下的內(nèi)容劫映,我們介紹幾個重要的目錄:

  • /bin/sbin:鏈接到 /usr/bin刹前,存放 Linux 一些核心的二進制文件,其包含的命令可在 shell 上運行雌桑。
  • /boot:操作系統(tǒng)啟動時要用到的程序喇喉。
  • /dev:包含了所有 Linux 系統(tǒng)中使用的外部設(shè)備。需要注意的是這里并不是存放外部設(shè)備的驅(qū)動程序校坑,而是一個訪問這些設(shè)備的端口拣技。
  • /etc:存放系統(tǒng)管理時要用到的各種配置文件和子目錄千诬。
  • /etc/rc.d:存放 Linux 啟動和關(guān)閉時要用到的腳本。
  • /home:普通用戶的主目錄膏斤。
  • /lib徐绑、/lib64:鏈接到 /usr/lib,存放系統(tǒng)及軟件需要的動態(tài)鏈接共享庫莫辨。
  • /mnt:這個目錄讓用戶可以臨時掛載其他的文件系統(tǒng)傲茄。
  • /proc:虛擬的目錄,是系統(tǒng)內(nèi)存的映射沮榜∨陶ィ可直接訪問這個目錄來獲取系統(tǒng)信息。
  • /root:系統(tǒng)管理員的主目錄蟆融。
  • /srv:存放一些服務(wù)啟動之后需要提取的數(shù)據(jù)草巡。
  • /sys:該目錄下安裝了一個文件系統(tǒng) sysfs。該文件系統(tǒng)是內(nèi)核設(shè)備樹的一個直觀反映型酥。當一個內(nèi)核對象被創(chuàng)建時山憨,對應(yīng)的文件和目錄也在內(nèi)核對象子系統(tǒng)中被創(chuàng)建。
  • /tmp:公用的臨時文件存放目錄弥喉。
  • /usr:應(yīng)用程序和文件幾乎都在這個目錄下郁竟。
  • /usr/src:內(nèi)核源代碼的存放目錄。
  • /var:存放了很多服務(wù)的日志信息档桃。

進程管理

  • top
    • 可以實時動態(tài)地查看系統(tǒng)的整體運行情況枪孩。
  • ps
    • 用于報告當前系統(tǒng)的進程狀態(tài)。可以搭配 kill 指令隨時中斷掏秩、刪除不必要的程序入偷。
    • 查看某進程的狀態(tài):$ ps -aux | grep [file],其中返回內(nèi)容最左邊的數(shù)字為進程號(PID)攻询。
  • kill
    • 用來刪除執(zhí)行中的程序或工作。
    • 刪除進程某 PID 指定的進程:$ kill [PID]

UID 和 GID

Linux 是一個支持多用戶的操作系統(tǒng)州弟,每個用戶都有 User ID(UID) 和 Group ID(GID)钧栖,UID 是對一個用戶的單一身份標識,而 GID 則對應(yīng)多個 UID婆翔。知道某個用戶的 UID 和 GID 是非常有用的拯杠,一些程序可能就需要 UID/GID 來運行】信可以使用 id 命令來查看:

$ id root
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),19(log)
$ id firmy
uid=1000(firmy) gid=1000(firmy) groups=1000(firmy),3(sys),7(lp),10(wheel),90(network),91(video),93(optical),95(storage),96(scanner),98(power),56(bumblebee)

UID 為 0 的 root 用戶類似于系統(tǒng)管理員潭陪,它具有系統(tǒng)的完全訪問權(quán)。我自己新建的用戶 firmy,其 UID 為 1000依溯,是一個普通用戶老厌。GID 的關(guān)系存儲在 /etc/group 文件中:

$ cat /etc/group
root:x:0:root
bin:x:1:root,bin,daemon
daemon:x:2:root,bin,daemon
sys:x:3:root,bin,firmy
......

所有用戶的信息(除了密碼)都保存在 /etc/passwd 文件中,而為了安全起見黎炉,加密過的用戶密碼保存在 /etc/shadow 文件中枝秤,此文件只有 root 權(quán)限可以訪問。

$ sudo cat /etc/shadow
root:$6$root$wvK.pRXFEH80GYkpiu1tEWYMOueo4tZtq7mYnldiyJBZDMe.mKwt.WIJnehb4bhZchL/93Oe1ok9UwxYf79yR1:17264::::::
firmy:$6$firmy$dhGT.WP91lnpG5/10GfGdj5L1fFVSoYlxwYHQn.llc5eKOvr7J8nqqGdVFKykMUSDNxix5Vh8zbXIapt0oPd8.:17264:0:99999:7:::

由于普通用戶的權(quán)限比較低慷嗜,這里使用 sudo 命令可以讓普通用戶以 root 用戶的身份運行某一命令淀弹。使用 su 命令則可以切換到一個不同的用戶:

$ whoami
firmy
$ su root
# whoami
root

whoami 用于打印當前有效的用戶名稱,shell 中普通用戶以 $ 開頭洪添,root 用戶以 # 開頭垦页。在輸入密碼后,我們已經(jīng)從 firmy 用戶轉(zhuǎn)換到 root 用戶了干奢。

權(quán)限設(shè)置

在 Linux 中痊焊,文件或目錄權(quán)限的控制分別以讀取、寫入忿峻、執(zhí)行 3 種一般權(quán)限來區(qū)分薄啥,另有 3 種特殊權(quán)限可供運用。

使用 ls -l [file] 來查看某文件或目錄的信息:

$ ls -l /
lrwxrwxrwx   1 root root     7 Jun 21 22:44 bin -> usr/bin
drwxr-xr-x   4 root root  4096 Jul 28 08:48 boot
-rw-r--r--   1 root root 18561 Apr  2 22:48 desktopfs-pkgs.txt

第一欄從第二個字母開始就是權(quán)限字符串逛尚,權(quán)限表示三個為一組垄惧,依次是所有者權(quán)限、組權(quán)限绰寞、其他人權(quán)限到逊。每組的順序均為 rwx,如果有相應(yīng)權(quán)限滤钱,則表示成相應(yīng)字母觉壶,如果不具有相應(yīng)權(quán)限,則用 - 表示件缸。

  • r:讀取權(quán)限,數(shù)字代號為 “4”
  • w:寫入權(quán)限他炊,數(shù)字代號為 “2”
  • x:執(zhí)行或切換權(quán)限,數(shù)字代號為 “1”

通過第一欄的第一個字母可知蚕苇,第一行是一個鏈接文件 (l),第二行是個目錄(d)凿叠,第三行是個普通文件(-)涩笤。

用戶可以使用 chmod 指令去變更文件與目錄的權(quán)限。權(quán)限范圍被指定為所有者(u)、所屬組(g)履恩、其他人(o)和所有人(a)锰茉。

  • -R:遞歸處理,將指令目錄下的所有文件及子目錄一并處理切心;
  • <權(quán)限范圍>+<權(quán)限設(shè)置>:開啟權(quán)限范圍的文件或目錄的該選項權(quán)限設(shè)置
    • $ chmod a+r [file]:賦予所有用戶讀取權(quán)限
  • <權(quán)限范圍>-<權(quán)限設(shè)置>:關(guān)閉權(quán)限范圍的文件或目錄的該選項權(quán)限設(shè)置
    • $ chmod u-w [file]:取消所有者寫入權(quán)限
  • <權(quán)限范圍>=<權(quán)限設(shè)置>:指定權(quán)限范圍的文件或目錄的該選項權(quán)限設(shè)置;
    • $ chmod g=x [file]:指定組權(quán)限為可執(zhí)行
    • $ chmod o=rwx [file]:制定其他人權(quán)限為可讀绽昏、可寫和可執(zhí)行

[圖片上傳失敗...(image-299768-1561871018467)]

字節(jié)序

目前計算機中采用兩種字節(jié)存儲機制:大端(Big-endian)和小端(Little-endian)。

MSB (Most Significan Bit/Byte):最重要的位或最重要的字節(jié)肤晓。

LSB (Least Significan Bit/Byte):最不重要的位或最不重要的字節(jié)认然。

Big-endian 規(guī)定 MSB 在存儲時放在低地址,在傳輸時放在流的開始卷员;LSB 存儲時放在高地址,在傳輸時放在流的末尾削饵。Little-endian 則相反未巫。常見的 Intel 處理器使用 Little-endian,而 PowerPC 系列處理器則使用 Big-endian尤仍,另外 TCP/IP 協(xié)議和 Java 虛擬機的字節(jié)序也是 Big-endian狭姨。

例如十六進制整數(shù) 0x12345678 存入以 1000H 開始的內(nèi)存中:

[圖片上傳失敗...(image-6dac46-1561871018467)]

我們在內(nèi)存中實際地看一下,在地址 0xffffd584 處有字符 1234饼拍,在地址 0xffffd588 處有字符 5678

gdb-peda$ x/w 0xffffd584
0xffffd584:     0x34333231
gdb-peda$ x/4wb 0xffffd584
0xffffd584:     0x31    0x32    0x33    0x34
gdb-peda$ python print('\x31\x32\x33\x34')
1234

gdb-peda$ x/w 0xffffd588
0xffffd588:     0x38373635
gdb-peda$ x/4wb 0xffffd588
0xffffd588:     0x35    0x36    0x37    0x38
gdb-peda$ python print('\x35\x36\x37\x38')
5678

gdb-peda$ x/2w 0xffffd584
0xffffd584:     0x34333231      0x38373635
gdb-peda$ x/8wb 0xffffd584
0xffffd584:     0x31    0x32    0x33    0x34    0x35    0x36    0x37    0x38
gdb-peda$ python print('\x31\x32\x33\x34\x35\x35\x36\x37\x38')
123455678
db-peda$ x/s 0xffffd584
0xffffd584:     "12345678"

輸入輸出

  • 使用命令的輸出作為可執(zhí)行文件的輸入?yún)?shù)
    • $ ./vulnerableyour_command_here``
    • $ ./vulnerable $(your_command_here)
  • 使用命令作為輸入
    • $ your_command_here | ./vulnerable
  • 將命令行輸出寫入文件
    • $ your_command_here > filename
  • 使用文件作為輸入
    • $ ./vulnerable < filename

文件描述符

在 Linux 系統(tǒng)中一切皆可以看成是文件漓柑,文件又分為:普通文件、目錄文件辆布、鏈接文件和設(shè)備文件。文件描述符(file descriptor)是內(nèi)核管理已被打開的文件所創(chuàng)建的索引景用,使用一個非負整數(shù)來指代被打開的文件惭蹂。

標準文件描述符如下:

文件描述符 用途 stdio 流
0 標準輸入 stdin
1 標準輸出 stdout
2 標準錯誤 stderr

當一個程序使用 fork() 生成一個子進程后,子進程會繼承父進程所打開的文件表,此時弃鸦,父子進程使用同一個文件表,這可能導致一些安全問題。如果使用 vfork()碳抄,子進程雖然運行于父進程的空間徐裸,但擁有自己的進程表項贫贝。

核心轉(zhuǎn)儲

當程序運行的過程中異常終止或崩潰患雇,操作系統(tǒng)會將程序當時的內(nèi)存、寄存器狀態(tài)酪术、堆棧指針翠储、內(nèi)存管理信息等記錄下來,保存在一個文件中咧七,這種行為就叫做核心轉(zhuǎn)儲(Core Dump)任斋。

會產(chǎn)生核心轉(zhuǎn)儲的信號

Signal Action Comment
SIGQUIT Core Quit from keyboard
SIGILL Core Illegal Instruction
SIGABRT Core Abort signal from abort
SIGSEGV Core Invalid memory reference
SIGTRAP Core Trace/breakpoint trap

開啟核心轉(zhuǎn)儲

  • 輸入命令 ulimit -c,輸出結(jié)果為 0瘟檩,說明默認是關(guān)閉的澈蟆。

  • 輸入命令 ulimit -c unlimited 即可在當前終端開啟核心轉(zhuǎn)儲功能。

  • 如果想讓核心轉(zhuǎn)儲功能永久開啟睹簇,可以修改文件 /etc/security/limits.conf,增加一行:

    #<domain>      <type>  <item>         <value>
    *               soft    core            unlimited
    

修改轉(zhuǎn)儲文件保存路徑

  • 通過修改 /proc/sys/kernel/core_uses_pid磨淌,可以使生成的核心轉(zhuǎn)儲文件名變?yōu)?core.[pid] 的模式凿渊。

    # echo 1 > /proc/sys/kernel/core_uses_pid
    
  • 還可以修改 /proc/sys/kernel/core_pattern 來控制生成核心轉(zhuǎn)儲文件的保存位置和文件名格式。

    # echo /tmp/core-%e-%p-%t > /proc/sys/kernel/core_pattern
    

    此時生成的文件保存在 /tmp/ 目錄下搪锣,文件名格式為 core-[filename]-[pid]-[time]彩掐。

使用 gdb 調(diào)試核心轉(zhuǎn)儲文件

gdb [filename] [core file]

例子

$ cat core.c
#include <stdio.h>
void main(int argc, char **argv) {
    char buf[5];
    scanf("%s", buf);
}
$ gcc -m32 -fno-stack-protector core.c
$ ./a.out
AAAAAAAAAAAAAAAAAAAA
Segmentation fault (core dumped)
$ file /tmp/core-a.out-12444-1503198911
/tmp/core-a.out-12444-1503198911: ELF 32-bit LSB core file Intel 80386, version 1 (SYSV), SVR4-style, from './a.out', real uid: 1000, effective uid: 1000, real gid: 1000, effective gid: 1000, execfn: './a.out', platform: 'i686'
$ gdb a.out /tmp/core-a.out-12444-1503198911 -q
Reading symbols from a.out...(no debugging symbols found)...done.
[New LWP 12444]
Core was generated by `./a.out'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x5655559b in main ()
gdb-peda$ info frame
Stack level 0, frame at 0x41414141:
 eip = 0x5655559b in main; saved eip = <not saved>
 Outermost frame: Cannot access memory at address 0x4141413d
 Arglist at 0x41414141, args:
 Locals at 0x41414141, Previous frame's sp is 0x41414141
Cannot access memory at address 0x4141413d

調(diào)用約定

函數(shù)調(diào)用約定是對函數(shù)調(diào)用時如何傳遞參數(shù)的一種約定佩谷。關(guān)于它的約定有許多種监嗜,下面我們分別從內(nèi)核接口和用戶接口介紹 32 位和 64 位 Linux 的調(diào)用約定。

內(nèi)核接口

x86-32 系統(tǒng)調(diào)用約定:Linux 系統(tǒng)調(diào)用使用寄存器傳遞參數(shù)桐猬。eax 為 syscall_number刽肠,ebxecx音五、edx躺涝、esiebp 用于將 6 個參數(shù)傳遞給系統(tǒng)調(diào)用坚嗜。返回值保存在 eax 中苍蔬。所有其他寄存器(包括 EFLAGS)都保留在 int 0x80 中。

x86-64 系統(tǒng)調(diào)用約定:內(nèi)核接口使用的寄存器有:rdi碟绑、rsirdx辜荠、r10r8造烁、r9午笛。系統(tǒng)調(diào)用通過 syscall 指令完成。除了 rcx告组、r11rax癌佩,其他的寄存器都被保留。系統(tǒng)調(diào)用的編號必須在寄存器 rax 中傳遞我碟。系統(tǒng)調(diào)用的參數(shù)限制為 6 個姚建,不直接從堆棧上傳遞任何參數(shù)。返回時厘托,rax 中包含了系統(tǒng)調(diào)用的結(jié)果稿湿。而且只有 INTEGER 或者 MEMORY 類型的值才會被傳遞給內(nèi)核。

用戶接口

x86-32 函數(shù)調(diào)用約定:參數(shù)通過棧進行傳遞伊群。最后一個參數(shù)第一個被放入棧中策精,直到所有的參數(shù)都放置完畢,然后執(zhí)行 call 指令丸卷。這也是 Linux 上 C 語言函數(shù)的方式询刹。

x86-64 函數(shù)調(diào)用約定:x86-64 下通過寄存器傳遞參數(shù)萎坷,這樣做比通過棧有更高的效率沐兰。它避免了內(nèi)存中參數(shù)的存取和額外的指令住闯。根據(jù)參數(shù)類型的不同,會使用寄存器或傳參方式比原。如果參數(shù)的類型是 MEMORY量窘,則在棧上傳遞參數(shù)。如果類型是 INTEGER蚌铜,則順序使用 rdi冬殃、rsirdx造壮、rcx耳璧、r8r9展箱。所以如果有多于 6 個的 INTEGER 參數(shù),則后面的參數(shù)在棧上傳遞攀隔。

環(huán)境變量

環(huán)境變量字符串都是 name=value 這樣的形式栖榨。大多數(shù) name 由大寫字母加下畫線組成,一般把 name 部分叫做環(huán)境變量名满粗,value 部分則是環(huán)境變量的值愚争,而且 value 需要以 "/0" 結(jié)尾挤聘,環(huán)境變量定義了該進程的運行環(huán)境捅彻。

分類

  • 按照生命周期劃分
    • 永久環(huán)境變量:修改相關(guān)配置文件步淹,永久生效。
    • 臨時環(huán)境變量:使用 export 命令广料,在當前終端下生效幼驶,關(guān)閉終端后失效。
  • 按照作用域劃分
    • 系統(tǒng)環(huán)境變量:對該系統(tǒng)中所有用戶生效购桑。
    • 用戶環(huán)境變量:對特定用戶生效氏淑。

設(shè)置方法

  • 在文件 /etc/profile 中添加變量,這種方法對所有用戶永久生效缭贡。如:

    # Set our default path
    PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"
    export PATH
    

    添加后執(zhí)行命令 source /etc/profile 使其生效辉懒。

  • 在文件 ~/.bash_profile 中添加變量,這種方法對當前用戶永久生效莹汤。其余同上颠印。

  • 直接運行命令 export 定義變量,這種方法只對當前終端臨時生效止潮。

常用變量

使用命令 echo 打印變量:

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
$ echo $HOME
/home/firmy
$ echo $LOGNAME
firmy
$ echo $HOSTNAME
firmy-pc
$ echo $SHELL
/bin/bash
$ echo $LANG
en_US.UTF-8

使用命令 env 可以打印出所有環(huán)境變量:

$ env
COLORFGBG=15;0
COLORTERM=truecolor
...

使用命令 set 可以打印處所有本地定義的 shell 變量:

$ set
'!'=0
'#'=0
...

使用命令 unset 可以清除變量:

unset $變量名

LD_PRELOAD

該環(huán)境變量可以定義在程序運行前優(yōu)先加載的動態(tài)鏈接庫钞楼。在 pwn 題目中,我們可能需要一個特定的 libc仅偎,這時就可以定義該變量:

LD_PRELOAD=/path/to/libc.so ./binary

一個例子:

$ ldd /bin/true
  linux-vdso.so.1 =>  (0x00007fff9a9fe000)
  libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1c083d9000)
  /lib64/ld-linux-x86-64.so.2 (0x0000557bcce6c000)
$ LD_PRELOAD=~/libc.so.6 ldd /bin/true
  linux-vdso.so.1 =>  (0x00007ffee55e9000)
  /home/firmy/libc.so.6 (0x00007f4a28cfc000)
  /lib64/ld-linux-x86-64.so.2 (0x000055f33bc50000)

注意橘沥,在加載動態(tài)鏈接庫時需要使用 ld.so 進行重定位,通常被符號鏈接到 /lib64/ld-linux-x86-64.so 中痢艺。動態(tài)鏈接庫在編譯時隱式指定 ld.so 的搜索路徑介陶,并寫入 ELF Header 的 INTERP 字段中。從其他發(fā)行版直接拷貝已編譯的 .so 文件可能會引發(fā) ld.so 搜索路徑不正確的問題舌缤。相似的某残,在版本依賴高度耦合的發(fā)行版中(如 ArchLinux),版本相差過大也會引發(fā) ld.so 的運行失敗介牙。

本地同版本編譯后通常不會出現(xiàn)問題澳厢。如果有直接拷貝已編譯版本的需要剩拢,可以對比 interpreter 確定是否符合要求,但是不保證不會失敗裸扶。

上面的例子中兩個 libc 是這樣的:

$ file /lib/x86_64-linux-gnu/libc-2.23.so
/lib/x86_64-linux-gnu/libc-2.23.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=088a6e00a1814622219f346b41e775b8dd46c518, for GNU/Linux 2.6.32, stripped
$ file ~/libc.so.6
/home/firmy/libc.so.6: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=088a6e00a1814622219f346b41e775b8dd46c518, for GNU/Linux 2.6.32, stripped

都是 interpreter /lib64/ld-linux-x86-64.so.2呵晨,所以可以替換熬尺。

而下面的例子是在 Arch Linux 上使用一個 Ubuntu 的 libc,就會出錯:

$ ldd /bin/true
        linux-vdso.so.1 (0x00007ffc969df000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007f7ddde17000)
        /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f7dde3d7000)
$ LD_PRELOAD=~/libc.so.6 ldd /bin/true
Illegal instruction (core dumped)
$ file /usr/lib/libc-2.26.so
/usr/lib/libc-2.26.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /usr/lib/ld-linux-x86-64.so.2, BuildID[sha1]=458fd9997a454786f071cfe2beb234542c1e871f, for GNU/Linux 3.2.0, not stripped
$ file ~/libc.so.6
/home/firmy/libc.so.6: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=088a6e00a1814622219f346b41e775b8dd46c518, for GNU/Linux 2.6.32, stripped

一個在 interpreter /usr/lib/ld-linux-x86-64.so.2季二,而另一個在 interpreter /lib64/ld-linux-x86-64.so.2胯舷。

environ

libc 中定義的全局變量 environ 指向環(huán)境變量表。而環(huán)境變量表存在于棧上桑嘶,所以通過 environ 指針的值就可以泄露出棧地址逃顶。

gdb-peda$ vmmap libc
Start              End                Perm      Name
0x00007ffff7a1c000 0x00007ffff7bcf000 r-xp      /usr/lib/libc-2.27.so
0x00007ffff7bcf000 0x00007ffff7dce000 ---p      /usr/lib/libc-2.27.so
0x00007ffff7dce000 0x00007ffff7dd2000 r--p      /usr/lib/libc-2.27.so
0x00007ffff7dd2000 0x00007ffff7dd4000 rw-p      /usr/lib/libc-2.27.so
gdb-peda$ vmmap stack
Start              End                Perm      Name
0x00007ffffffde000 0x00007ffffffff000 rw-p      [stack]
gdb-peda$ shell nm -D /usr/lib/libc-2.27.so | grep environ
00000000003b8ee0 V environ
00000000003b8ee0 V _environ
00000000003b8ee0 B __environ
gdb-peda$ x/gx 0x00007ffff7a1c000 + 0x00000000003b8ee0
0x7ffff7dd4ee0 <environ>:       0x00007fffffffde48
gdb-peda$ x/5gx 0x00007fffffffde48
0x7fffffffde48: 0x00007fffffffe1da      0x00007fffffffe1e9
0x7fffffffde58: 0x00007fffffffe1fd      0x00007fffffffe233
0x7fffffffde68: 0x00007fffffffe25f
gdb-peda$ x/5s 0x00007fffffffe1da
0x7fffffffe1da: "COLORFGBG=15;0"
0x7fffffffe1e9: "COLORTERM=truecolor"
0x7fffffffe1fd: "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus"
0x7fffffffe233: "DESKTOP_SESSION=/usr/share/xsessions/plasma"
0x7fffffffe25f: "DISPLAY=:0"

procfs

procfs 文件系統(tǒng)是 Linux 內(nèi)核提供的虛擬文件系統(tǒng),為訪問系統(tǒng)內(nèi)核數(shù)據(jù)的操作提供接口霸褒。之所以說是虛擬文件系統(tǒng)盈蛮,是因為它不占用存儲空間眉反,而只是占用了內(nèi)存。用戶可以通過 procfs 查看有關(guān)系統(tǒng)硬件及當前正在運行進程的信息梳凛,甚至可以通過修改其中的某些內(nèi)容來改變內(nèi)核的運行狀態(tài)梳杏。

/proc/cmdline

在啟動時傳遞給內(nèi)核的相關(guān)參數(shù)信息,通常由 lilo 或 grub 等啟動管理工具提供:

$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-4.14-x86_64 root=UUID=8e79a67d-af1b-4203-8c1c-3b670f0ec052 rw quiet resume=UUID=a220ecb1-7fde-4032-87bf-413057e9c06f

/proc/cpuinfo

記錄 CPU 相關(guān)的信息:

$ cat /proc/cpuinfo
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 60
model name      : Intel(R) Core(TM) i5-4210H CPU @ 2.90GHz
stepping        : 3
microcode       : 0x24
cpu MHz         : 1511.087
cache size      : 3072 KB
physical id     : 0
siblings        : 4
core id         : 0
cpu cores       : 2
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 13
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm cpuid_fault epb invpcid_single pti ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt dtherm ida arat pln pts
bugs            : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass
bogomips        : 5788.66
clflush size    : 64
cache_alignment : 64
address sizes   : 39 bits physical, 48 bits virtual
power management:
...

/proc/crypto

已安裝的內(nèi)核所使用的密碼算法及算法的詳細信息:

$ cat /proc/crypto
name         : ccm(aes)
driver       : ccm_base(ctr(aes-aesni),cbcmac(aes-aesni))
module       : ccm
priority     : 300
refcnt       : 2
selftest     : passed
internal     : no
type         : aead
async        : no
blocksize    : 1
ivsize       : 16
maxauthsize  : 16
geniv        : <none>
...

/proc/devices

已加載的所有塊設(shè)備和字符設(shè)備的信息叛溢,包含主設(shè)備號和設(shè)備組(與主設(shè)備號對應(yīng)的設(shè)備類型)名:

$ cat /proc/devices
Character devices:
  1 mem
  4 /dev/vc/0
  4 tty
  4 ttyS
  5 /dev/tty
  5 /dev/console
...

/proc/interrupts

X86/X86_64 系統(tǒng)上每個 IRQ 相關(guān)的中斷號列表楷掉,多路處理器平臺上每個 CPU 對于每個 I/O 設(shè)備均有自己的中斷號:

$ cat /proc/interrupts
           CPU0       CPU1       CPU2       CPU3
  0:         15          0          0          0  IR-IO-APIC   2-edge      timer
  1:      46235       1277        325        156  IR-IO-APIC   1-edge      i8042
  8:          0          1          0          0  IR-IO-APIC   8-edge      rtc0
...
NMI:          0          0          0          0   Non-maskable interrupts
LOC:    7363806    5569019    6138317    5442200   Local timer interrupts
SPU:          0          0          0          0   Spurious interrupts
...

/proc/kcore

系統(tǒng)使用的物理內(nèi)存霞势,以 ELF 核心文件(core file)格式存儲:

$ sudo file /proc/kcore
/proc/kcore: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, from 'BOOT_IMAGE=/boot/vmlinuz-4.14-x86_64 root=UUID=8e79a67d-af1b-4203-8c1c-3b670f0e'

/proc/meminfo

系統(tǒng)中關(guān)于當前內(nèi)存的利用狀況等的信息:

$ cat /proc/meminfo
MemTotal:       12226252 kB
MemFree:         4909444 kB
MemAvailable:    8776048 kB
Buffers:          288236 kB
Cached:          3953616 kB
...

/proc/mounts

每個進程自身掛載名稱空間中的所有掛載點列表文件的符號鏈接:

$ cat /proc/mounts
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
sys /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
dev /dev devtmpfs rw,nosuid,relatime,size=6106264k,nr_inodes=1526566,mode=755 0 0
...

/proc/modules

當前裝入內(nèi)核的所有模塊名稱列表愕贡,可以由 lsmod 命令使用。其中第一列表示模塊名墩虹,第二列表示此模塊占用內(nèi)存空間大小,第三列表示此模塊有多少實例被裝入旬昭,第四列表示此模塊依賴于其它哪些模塊菌湃,第五列表示此模塊的裝載狀態(tài):Live(已經(jīng)裝入)、Loading(正在裝入)和 Unloading(正在卸載)场梆,第六列表示此模塊在內(nèi)核內(nèi)存(kernel memory)中的偏移量:

$ cat /proc/modules
fuse 118784 3 - Live 0xffffffffc0d9b000
ccm 20480 3 - Live 0xffffffffc0d95000
rfcomm 86016 4 - Live 0xffffffffc0d7f000
bnep 24576 2 - Live 0xffffffffc0d78000
...

/proc/slabinfo

保存著監(jiān)視系統(tǒng)中所有活動的 slab 緩存的信息:

$ sudo cat /proc/slabinfo
slabinfo - version: 2.1
# name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
fuse_request           0     20    400   20    2 : tunables    0    0    0 : slabdata      1      1      0
fuse_inode             1     39    832   39    8 : tunables    0    0    0 : slabdata      1      1      0
drm_i915_gem_request    765   1036    576   28    4 : tunables    0    0    0 : slabdata     37     37      0
...

/proc/[pid]

在 /proc 文件系統(tǒng)下纯路,還有一些以數(shù)字命名的目錄驰唬,這些數(shù)字是進程的 PID 號,而這些目錄是進程目錄叫编。目錄下的所有文件如下搓逾,然后會介紹幾個比較重要的:

$ cat - &
[1] 1060
$ ls /proc/1060/
attr        comm             fd         maps        ns             personality  smaps         syscall
autogroup   coredump_filter  fdinfo     mem         numa_maps      projid_map   smaps_rollup  task
auxv        cpuset           gid_map    mountinfo   oom_adj        root         stack         timers
cgroup      cwd              io         mounts      oom_score      sched        stat          timerslack_ns
clear_refs  environ          limits     mountstats  oom_score_adj  schedstat    statm         uid_map
cmdline     exe              map_files  net         pagemap        setgroups    status        wchan

/proc/[pid]/cmdline

啟動當前進程的完整命令:

$ cat /proc/1060/cmdline
cat-

/proc/[pid]/exe

指向啟動當前進程的可執(zhí)行文件的符號鏈接:

$ file /proc/1060/exe
/proc/1060/exe: symbolic link to /usr/bin/cat

/proc/[pid]/root

當前進程運行根目錄的符號鏈接:

$ file /proc/1060/root
/proc/1060/root: symbolic link to /

/proc/[pid]/mem

當前進程所占用的內(nèi)存空間,由open世蔗、read和lseek等系統(tǒng)調(diào)用使用朗兵,不能被用戶讀取余掖。但可通過下面的 /proc/[pid]/maps 查看。

/proc/[pid]/maps

這個文件大概是最常用的盐欺,用于顯示進程的內(nèi)存區(qū)域映射信息:

$ cat /proc/1060/maps
56271b3a5000-56271b3ad000 r-xp 00000000 08:01 24904069                   /usr/bin/cat
56271b5ac000-56271b5ad000 r--p 00007000 08:01 24904069                   /usr/bin/cat
56271b5ad000-56271b5ae000 rw-p 00008000 08:01 24904069                   /usr/bin/cat
56271b864000-56271b885000 rw-p 00000000 00:00 0                          [heap]
7fefb66cd000-7fefb6a1e000 r--p 00000000 08:01 24912207                   /usr/lib/locale/locale-archive
7fefb6a1e000-7fefb6bd1000 r-xp 00000000 08:01 24905238                   /usr/lib/libc-2.27.so
7fefb6bd1000-7fefb6dd0000 ---p 001b3000 08:01 24905238                   /usr/lib/libc-2.27.so
7fefb6dd0000-7fefb6dd4000 r--p 001b2000 08:01 24905238                   /usr/lib/libc-2.27.so
7fefb6dd4000-7fefb6dd6000 rw-p 001b6000 08:01 24905238                   /usr/lib/libc-2.27.so
7fefb6dd6000-7fefb6dda000 rw-p 00000000 00:00 0
7fefb6dda000-7fefb6dff000 r-xp 00000000 08:01 24905239                   /usr/lib/ld-2.27.so
7fefb6fbd000-7fefb6fbf000 rw-p 00000000 00:00 0
7fefb6fdc000-7fefb6ffe000 rw-p 00000000 00:00 0
7fefb6ffe000-7fefb6fff000 r--p 00024000 08:01 24905239                   /usr/lib/ld-2.27.so
7fefb6fff000-7fefb7000000 rw-p 00025000 08:01 24905239                   /usr/lib/ld-2.27.so
7fefb7000000-7fefb7001000 rw-p 00000000 00:00 0
7ffde5659000-7ffde567a000 rw-p 00000000 00:00 0                          [stack]
7ffde5748000-7ffde574b000 r--p 00000000 00:00 0                          [vvar]
7ffde574b000-7ffde574d000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

/proc/[pid]/stack

這個文件表示當前進程的內(nèi)核調(diào)用棧信息找田,只有在內(nèi)核編譯啟用 CONFIG_STACKTRACE 選項着憨,才會生成該文件:

$ sudo cat /proc/1060/stack
[<ffffffff8e08fa2e>] do_signal_stop+0xae/0x1f0
[<ffffffff8e090ec1>] get_signal+0x191/0x580
[<ffffffff8e02ae56>] do_signal+0x36/0x610
[<ffffffff8e003669>] exit_to_usermode_loop+0x69/0xa0
[<ffffffff8e0039d1>] do_syscall_64+0xf1/0x100
[<ffffffff8e800081>] entry_SYSCALL_64_after_hwframe+0x3d/0xa2
[<ffffffffffffffff>] 0xffffffffffffffff

/proc/[pid]/auxv

該文件包含了傳遞給進程的解釋器信息,即 auxv(AUXiliary Vector)漆改,每一項都是由一個 unsigned long 長度的 ID 加上一個 unsigned long 長度的值構(gòu)成:

$ xxd -e -g8 /proc/1060/auxv
00000000: 0000000000000021 00007ffde574b000  !.........t.....
00000010: 0000000000000010 00000000bfebfbff  ................
00000020: 0000000000000006 0000000000001000  ................
00000030: 0000000000000011 0000000000000064  ........d.......
00000040: 0000000000000003 000056271b3a5040  ........@P:.'V..
00000050: 0000000000000004 0000000000000038  ........8.......
00000060: 0000000000000005 0000000000000009  ................
00000070: 0000000000000007 00007fefb6dda000  ................
00000080: 0000000000000008 0000000000000000  ................
00000090: 0000000000000009 000056271b3a7260  ........`r:.'V..
000000a0: 000000000000000b 00000000000003e8  ................
000000b0: 000000000000000c 00000000000003e8  ................
000000c0: 000000000000000d 00000000000003e8  ................
000000d0: 000000000000000e 00000000000003e8  ................
000000e0: 0000000000000017 0000000000000000  ................
000000f0: 0000000000000019 00007ffde5678349  ........I.g.....
00000100: 000000000000001a 0000000000000000  ................
00000110: 000000000000001f 00007ffde5679fef  ..........g.....
00000120: 000000000000000f 00007ffde5678359  ........Y.g.....
00000130: 0000000000000000 0000000000000000  ................

每個值具體是做什么的挫剑,可以用下面的辦法顯示出來樊破,對比看一看,更詳細的可以查看 /usr/include/elf.hman ld.so

$ LD_SHOW_AUXV=1 cat -
AT_SYSINFO_EHDR: 0x7ffd16be5000
AT_HWCAP:        bfebfbff
AT_PAGESZ:       4096
AT_CLKTCK:       100
AT_PHDR:         0x55eb4c59a040
AT_PHENT:        56
AT_PHNUM:        9
AT_BASE:         0x7f61506e8000
AT_FLAGS:        0x0
AT_ENTRY:        0x55eb4c59c260
AT_UID:          1000
AT_EUID:         1000
AT_GID:          1000
AT_EGID:         1000
AT_SECURE:       0
AT_RANDOM:       0x7ffd16bd0ce9
AT_HWCAP2:       0x0
AT_EXECFN:       /bin/cat
AT_PLATFORM:     x86_64

值得一提的是奔滑,AT_SYSINFO_EHDR 所對應(yīng)的值是一個叫做的 VDSO(Virtual Dynamic Shared Object) 的地址顺少。在 ret2vdso 漏洞利用方法中會用到(參考章節(jié)6.1.6)。

/proc/[pid]/environ

該文件包含了進程的環(huán)境變量:

$ strings /proc/1060/environ
GS_LIB=/home/firmy/.fonts
KDE_FULL_SESSION=true
VIRTUALENVWRAPPER_WORKON_CD=1
VIRTUALENVWRAPPER_HOOK_DIR=/home/firmy/.virtualenvs
LANG=zh_CN.UTF-8
...

/proc/[pid]/fd

該文件包含了進程打開文件的情況:

$ ls -al /proc/1060/fd
total 0
dr-x------ 2 firmy firmy  0 6月   7 23:37 .
dr-xr-xr-x 9 firmy firmy  0 6月   7 23:37 ..
lrwx------ 1 firmy firmy 64 6月   7 23:44 0 -> /dev/pts/3
lrwx------ 1 firmy firmy 64 6月   7 23:44 1 -> /dev/pts/3
lrwx------ 1 firmy firmy 64 6月   7 23:44 2 -> /dev/pts/3

/proc/[pid]/status

該文件包含了進程的狀態(tài)信息:

$ cat /proc/1060/status
Name:   cat
Umask:  0022
State:  T (stopped)
Tgid:   1060
Ngid:   0
Pid:    1060
PPid:   1035
TracerPid:      0
Uid:    1000    1000    1000    1000
Gid:    1000    1000    1000    1000
FDSize: 256
Groups: 3 7 10 56 90 91 93 95 96 98 1000
...

/proc/[pid]/task

一個目錄梅猿,包含當前進程的每一個線程的相關(guān)信息秒裕,每個線程的信息分別放在一個由線程號(tid)命名的目錄中:

$ ls /proc/1060/task/
1060
$ ls /proc/1060/task/1060/
attr      clear_refs  cwd      fdinfo   maps       net        oom_score      projid_map  setgroups     stat     uid_map
auxv      cmdline     environ  gid_map  mem        ns         oom_score_adj  root        smaps         statm    wchan
cgroup    comm        exe      io       mountinfo  numa_maps  pagemap        sched       smaps_rollup  status
children  cpuset      fd       limits   mounts     oom_adj    personality    schedstat   stack         syscall

/proc/[pid]/syscall

該文件包含了進程正在執(zhí)行的系統(tǒng)調(diào)用:

$ sudo cat /proc/1060/syscall
0 0x0 0x7fefb6fdd000 0x20000 0x22 0xffffffff 0x0 0x7ffde5677d48 0x7fefb6b07901

第一個值是系統(tǒng)調(diào)用號几蜻,后面跟著是六個參數(shù),最后兩個值分別是堆棧指針和指令計數(shù)器的值响蓉。

參考資料

來源:GitHub

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末哨毁,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子想幻,更是在濱河造成了極大的恐慌话浇,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件食店,死亡現(xiàn)場離奇詭異吉嫩,居然都是意外死亡,警方通過查閱死者的電腦和手機自娩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門忙迁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人丁屎,你說我怎么就攤上這事旱眯。” “怎么了共虑?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵呀页,是天一觀的道長蓬蝶。 經(jīng)常有香客問我,道長丸氛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任定续,我火速辦了婚禮私股,結(jié)果婚禮上恩掷,老公的妹妹穿的比我還像新娘。我一直安慰自己峭状,他們只是感情好,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著氮凝,像睡著了一般罩阵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上稿壁,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天傅是,我揣著相機與錄音,去河邊找鬼喧笔。 笑死书闸,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的浆劲。 我是一名探鬼主播牌借,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蚯嫌!你這毒婦竟也來了丙躏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤栅盲,失蹤者是張志新(化名)和其女友劉穎废恋,沒想到半個月后谈秫,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扒寄,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年拟烫,在試婚紗的時候發(fā)現(xiàn)自己被綠了该编。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡硕淑,死狀恐怖课竣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情置媳,我是刑警寧澤于樟,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站迂曲,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏寥袭。R本人自食惡果不足惜路捧,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望传黄。 院中可真熱鬧鬓长,春花似錦、人聲如沸尝江。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽炭序。三九已至啤覆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惭聂,已是汗流浹背窗声。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留辜纲,地道東北人笨觅。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像耕腾,于是被迫代替她去往敵國和親见剩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348