diff --git a/doc/1.3_linux_basic.md b/doc/1.3_linux_basic.md index dc2560d..3ce355d 100644 --- a/doc/1.3_linux_basic.md +++ b/doc/1.3_linux_basic.md @@ -1,6 +1,8 @@ # Linux 基础 - [常用基础命令](#常用基础命令) +- [进程管理](#进程管理) +- [权限设置](#权限设置) - [字节序](#字节序) - [输入输出](#输入输出) @@ -34,6 +36,45 @@ nano / vim / emacs 字符终端的文本编辑器 ``` +## 进程管理 +- top + - 可以实时动态地查看系统的整体运行情况。 +- ps + - 用于报告当前系统的进程状态。可以搭配 kill 指令随时中断、删除不必要的程序。 + - 查看某进程的状态:`$ ps -aux | grep [file]`,其中返回内容最左边的数字为进程号(PID)。 +- kill + - 用来删除执行中的程序或工作。 + - 删除进程某 PID 指定的进程:`$ kill [PID]` + + +## 权限设置 +在 Linux 中,文件或目录权限的控制分别以读取、写入、执行 3 种一般权限来区分,另有 3 种特殊权限可供运用。 + +使用 `ls -l [file]` 来查看某文件或目录的信息: +```text +$ 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 +``` +第一栏从第二个字母开始就是权限字符串,权限表示三个为一组,依次是所有者权限、组权限、其他人权限。每组的顺序均为 `rwx`,如果有相应权限,则表示成相应字母,如果不具有相应权限,则用 `-` 表示。 + - `r`:读取权限,数字代号为 “4” + - `w`:写入权限,数字代号为 “2” + - `x`:执行或切换权限,数字代号为 “1”; + +通过第一栏的第一个字母可知,第一行是一个链接文件 (`l`),第二行是个目录(`d`),第三行是个普通文件(`-`)。 + +用户可以使用 `chmod` 指令去变更文件与目录的权限。权限范围被指定为所有者(`u`)、所属组(`g`)、其他人(`o`)和所有人(`a`)。 +- -R:递归处理,将指令目录下的所有文件及子目录一并处理; +- <权限范围>+<权限设置>:开启权限范围的文件或目录的该选项权限设置 + - `$ chmod a+r [file]`:赋予所有用户读取权限 +- <权限范围>-<权限设置>:关闭权限范围的文件或目录的该选项权限设置 + - `$ chmod u-w [file]`:取消所有者写入权限 +- <权限范围>=<权限设置>:指定权限范围的文件或目录的该选项权限设置; + - `$ chmod g=x [file]`:指定组权限为可执行 + - `$ chmod o=rwx [file]`:制定其他人权限为可读、可写和可执行 + + ## 字节序 目前计算机中采用两种字节存储机制:大端(Big-endian)和小端(Little-endian)。 diff --git a/doc/4.2_Linux_terminal_tips.md b/doc/4.2_Linux_terminal_tips.md index 89cbfd1..2591e32 100644 --- a/doc/4.2_Linux_terminal_tips.md +++ b/doc/4.2_Linux_terminal_tips.md @@ -1,9 +1,97 @@ # Linux 命令行技巧 - [重定向输入字符](#重定向输入字符) +- [从可执行文件中提取 shellcode](#从可执行文件中提取-shellcode) +- [查看进程虚拟地址空间](#查看进程虚拟地址空间) ## 重定向输入字符 有时候我们需要在 shell 里输入键盘上没有对应的字符,如 `0x1F`,就需要使用重定向输入。下面是一个例子:[源码](../src/Others/4.2_0x1f.c) ![](../pic/4.2_0x1f.png) + + +## 从可执行文件中提取 shellcode +```text +for i in `objdump -d print_flag | tr '\t' ' ' | tr ' ' '\n' | egrep '^[0-9a-f]{2}$' ` ; do echo -n "\x$i" ; done +``` +注意:在 objdump 中空字节可能会被删除。 + + +## 查看进程虚拟地址空间 +有时我们需要知道一个进程的虚拟地址空间是如何使用的,以确定栈是否是可执行的。 +```text +$ cat /proc//maps +``` +下面我们分别来看看可执行栈和不可执行栈的不同: +```text +$ cat hello.c +#include +void main() +{ + char buf[128]; + scanf("hello, world: %s\n", buf); +} + +$ gcc hello.c -o a.out1 + +$ ./a.out1 & +[1] 7403 + +$ cat /proc/7403/maps +555555554000-555555555000 r-xp 00000000 08:01 26389924 /home/firmy/a.out1 +555555754000-555555755000 r--p 00000000 08:01 26389924 /home/firmy/a.out1 +555555755000-555555756000 rw-p 00001000 08:01 26389924 /home/firmy/a.out1 +555555756000-555555777000 rw-p 00000000 00:00 0 [heap] +7ffff7a33000-7ffff7bd0000 r-xp 00000000 08:01 21372436 /usr/lib/libc-2.25.so +7ffff7bd0000-7ffff7dcf000 ---p 0019d000 08:01 21372436 /usr/lib/libc-2.25.so +7ffff7dcf000-7ffff7dd3000 r--p 0019c000 08:01 21372436 /usr/lib/libc-2.25.so +7ffff7dd3000-7ffff7dd5000 rw-p 001a0000 08:01 21372436 /usr/lib/libc-2.25.so +7ffff7dd5000-7ffff7dd9000 rw-p 00000000 00:00 0 +7ffff7dd9000-7ffff7dfc000 r-xp 00000000 08:01 21372338 /usr/lib/ld-2.25.so +7ffff7fbc000-7ffff7fbe000 rw-p 00000000 00:00 0 +7ffff7ff8000-7ffff7ffa000 r--p 00000000 00:00 0 [vvar] +7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso] +7ffff7ffc000-7ffff7ffd000 r--p 00023000 08:01 21372338 /usr/lib/ld-2.25.so +7ffff7ffd000-7ffff7ffe000 rw-p 00024000 08:01 21372338 /usr/lib/ld-2.25.so +7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0 +7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack] +ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] + +[1]+ Stopped ./a.out1 + +$ gcc -z execstack hello.c -o a.out2 + +$ ./a.out2 & +[2] 7467 +[firmy@manjaro ~]$ cat /proc/7467/maps +555555554000-555555555000 r-xp 00000000 08:01 26366643 /home/firmy/a.out2 +555555754000-555555755000 r-xp 00000000 08:01 26366643 /home/firmy/a.out2 +555555755000-555555756000 rwxp 00001000 08:01 26366643 /home/firmy/a.out2 +555555756000-555555777000 rwxp 00000000 00:00 0 [heap] +7ffff7a33000-7ffff7bd0000 r-xp 00000000 08:01 21372436 /usr/lib/libc-2.25.so +7ffff7bd0000-7ffff7dcf000 ---p 0019d000 08:01 21372436 /usr/lib/libc-2.25.so +7ffff7dcf000-7ffff7dd3000 r-xp 0019c000 08:01 21372436 /usr/lib/libc-2.25.so +7ffff7dd3000-7ffff7dd5000 rwxp 001a0000 08:01 21372436 /usr/lib/libc-2.25.so +7ffff7dd5000-7ffff7dd9000 rwxp 00000000 00:00 0 +7ffff7dd9000-7ffff7dfc000 r-xp 00000000 08:01 21372338 /usr/lib/ld-2.25.so +7ffff7fbc000-7ffff7fbe000 rwxp 00000000 00:00 0 +7ffff7ff8000-7ffff7ffa000 r--p 00000000 00:00 0 [vvar] +7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso] +7ffff7ffc000-7ffff7ffd000 r-xp 00023000 08:01 21372338 /usr/lib/ld-2.25.so +7ffff7ffd000-7ffff7ffe000 rwxp 00024000 08:01 21372338 /usr/lib/ld-2.25.so +7ffff7ffe000-7ffff7fff000 rwxp 00000000 00:00 0 +7ffffffde000-7ffffffff000 rwxp 00000000 00:00 0 [stack] +ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] + +[2]+ Stopped ./a.out2 +``` +当使用 `-z execstack` 参数进行编译时,会关闭 `Stack Protector`。我们可以看到在 `a.out1` 中的 `stack` 是 `rw` 的,而 `a.out2` 中则是 `rwx` 的。 + +`maps` 文件有 6 列,分别为: +- **地址**:库在进程里地址范围 +- **权限**:虚拟内存的权限,r=读,w=写,x=执行,s=共享,p=私有 +- **偏移量**:库在进程里地址偏移量 +- **设备**:映像文件的主设备号和次设备号,可以通过通过 `cat /proc/devices` 查看设备号对应的设备名 +- **节点**:映像文件的节点号 +- **路径**: 映像文件的路径,经常同一个地址有两个地址范围,那是因为一段是 `r-xp` 为只读的代码段,一段是 `rwxp` 为可读写的数据段