update linux

This commit is contained in:
firmianay 2017-08-20 11:26:20 +08:00
parent 944a58a59c
commit 167f20f63b
2 changed files with 83 additions and 4 deletions

View File

@ -8,6 +8,7 @@
- [字节序](#字节序) - [字节序](#字节序)
- [输入输出](#输入输出) - [输入输出](#输入输出)
- [文件描述符](#文件描述符) - [文件描述符](#文件描述符)
- [核心转储](#核心转储)
## 常用基础命令 ## 常用基础命令
@ -191,3 +192,70 @@ Big-endian 规定 MSB 在存储时放在低地址,在传输时放在流的开
2 | 标准错误 | stderr 2 | 标准错误 | stderr
当一个程序使用 `fork()` 生成一个子进程后,子进程会继承父进程所打开的文件表,此时,父子进程使用同一个文件表,这可能导致一些安全问题。如果使用 `vfork()`,子进程虽然运行于父进程的空间,但拥有自己的进程表项。 当一个程序使用 `fork()` 生成一个子进程后,子进程会继承父进程所打开的文件表,此时,父子进程使用同一个文件表,这可能导致一些安全问题。如果使用 `vfork()`,子进程虽然运行于父进程的空间,但拥有自己的进程表项。
## 核心转储
当程序运行的过程中异常终止或崩溃操作系统会将程序当时的内存、寄存器状态、堆栈指针、内存管理信息等记录下来保存在一个文件中这种行为就叫做核心转储Core Dump
#### 会产生核心转储的信号
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
#### 开启核心转储
- 输入命令 `ulimit -c`,输出结果为 `0`,说明默认是关闭的。
- 输入命令 `ulimit -c unlimited` 即可在当前终端开启核心转储功能。
- 如果想让核心转储功能永久开启,可以修改文件 `/etc/security/limits.conf`,增加一行:
```
#<domain> <type> <item> <value>
* soft core unlimited
```
#### 修改转储文件保存路径
- 通过修改 `/proc/sys/kernel/core_uses_pid`,可以使生成的核心转储文件名变为 `core.[pid]` 的模式。
```
# echo 1 > /proc/sys/kernel/core_uses_pid
```
- 还可以修改 `/proc/sys/kernel/core_pattern` 来控制生成核心转储文件的保存位置和文件名格式。
```
# echo /tmp/core-%e-%p-%t > /proc/sys/kernel/core_pattern
```
此时生成的文件保存在 `/tmp/` 目录下,文件名格式为 `core-[filename]-[pid]-[time]`
#### 使用 gdb 调试核心转储文件
```text
$ gdb [filename] [core file]
```
#### 例子
```text
$ 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
```

View File

@ -1,8 +1,8 @@
# 格式化字符串漏洞 # 格式化字符串漏洞
- [格式化输出函数和格式字符串](格式化输出函数和格式字符串) - [格式化输出函数和格式字符串](#格式化输出函数和格式字符串)
- [格式化字符串漏洞基本原理](#格式化字符串漏洞基本原理) - [格式化字符串漏洞基本原理](#格式化字符串漏洞基本原理)
- [格式化字符串漏洞示例](#格式化字符串漏洞示例) - [格式化字符串漏洞](#格式化字符串漏洞)
- [CTF 中的格式化字符串漏洞](#ctf-中的格式化字符串漏洞) - [CTF 中的格式化字符串漏洞](#ctf-中的格式化字符串漏洞)
@ -141,7 +141,7 @@ Continuing
Hello World! 233 Hello World! 233
[Inferior 1 (process 27416) exited with code 022] [Inferior 1 (process 27416) exited with code 022]
``` ```
根据 cdecl 的调用约定,在进入 `printf()` 函数之前,将参数从右到左依次压栈。进入 `printf()` 之后,函数首先获取第一个参数,一次读取一个字符。如果字符不是 `%`,字符直接复制到输出中。否则,读取下一个字符,获取相应的参数并解析输出。 根据 cdecl 的调用约定,在进入 `printf()` 函数之前,将参数从右到左依次压栈。进入 `printf()` 之后,函数首先获取第一个参数,一次读取一个字符。如果字符不是 `%`,字符直接复制到输出中。否则,读取下一个非空字符,获取相应的参数并解析输出。(注意:`% d` 和 `%d` 是一样的)
接下来我们修改一下上面的程序,给格式字符串加上 `%x %x %x %3$s`,使它出现格式化字符串漏洞: 接下来我们修改一下上面的程序,给格式字符串加上 `%x %x %x %3$s`,使它出现格式化字符串漏洞:
```c ```c
@ -264,7 +264,18 @@ Hello 32 f7f95580 565555f4 !
- `printf()` 函数从栈中取出参数,如果它需要 3 个,那它就取出 3 个。除非栈的边界被标记了,否则 `printf()` 是不会知道它取出的参数比提供给它的参数多了。然而并没有这样的标记。 - `printf()` 函数从栈中取出参数,如果它需要 3 个,那它就取出 3 个。除非栈的边界被标记了,否则 `printf()` 是不会知道它取出的参数比提供给它的参数多了。然而并没有这样的标记。
## 格式化字符串漏洞示例 ## 格式化字符串漏洞
通过提供和格式字符串,我们就能够控制格式化函数的行为。漏洞的利用主要有下面几种。
#### 使程序崩溃
#### 查看栈
#### 查看任意地址的内存
#### 覆盖栈
#### 覆盖任意地址内存
## CTF 中的格式化字符串漏洞 ## CTF 中的格式化字符串漏洞