1. Tracee 介绍

1.1 Tracee 介绍

Tracee 是一个用 于 Linux 的运行时安全和取证工具。它使用 Linux eBPF 技术在运行时跟踪系统和应用程序,并分析收集的事件以检测可疑的行为模式。Tracee 以 Docker 镜像的形式交付,监控操作系统并根据预定义的行为模式集检测可疑行为。完整文档参见:https://aquasecurity.github.io/tracee/dev/

Tracee 由以下子项目组成:

  • Trace-eBPF - 使用 eBPF 进行 Linux 追踪和取证,BPF 底层代码实现参见 tracee.bpf.c

  • Trace-Rules - 运行时安全检测引擎,在真实的使用场景中通过管道的方式从 Trace-eBPF 中接受数据,具体运行命令 如下

    $TRACEE_EBPF_EXE --output=format:gob --security-alerts | $TRACEE_RULES_EXE --input-tracee=file:stdin --input-tracee=format:gob $@
  • libbpfgo 基于 Linux libbpf 的 Go 的 eBPF 库,Tracee 程序通过 cgo 访问 libbpf C 语言库;

Tracee 运行系统最低内核版本要求 >= 4.18,可以根据是否开启 CO-RE 进行 BPF 底层代码编译。运行 Tracee 需要足够的权限才能运行,测试可以直接使用 root 用户运行或者在 Docker 模型下使用 --privileged 模式运行。

Tracee 在最近的版本中增加了一个非常有意思的功能抓取 --capture,可以将读写文件、内存文件、网络数据包等进行抓取并保存,该功能主要是用于取证相关功能。

1.2 Tracee 与 Falco 的区别

看到 Tracee 这款基于 eBPF 技术的安全产品,很自然想到的对应产品是 Falco,如果你对 Falco 不了解,那么可以参见 这篇文章。 Tracee 与 Falco 还是有诸多类似的功能,只是从实现和架构上看, Tracee 更加直接和简单,也没有特别复杂的规则引擎,作者给出的与 Falco 定位不同如下,更加详细的可参见 这里

Falco 是一个规则引擎,基于 sysdig 的开放源代码。它从 sysdig 获取原始事件,并与 yaml 文件中 falco 语言定义的规则相匹配。相比之下,Tracee 从 eBPF 中追踪事件,但不执行基于这些事件的规则。

我们编写 Tracee 时考虑到了以下几点:

  • Tracee 从一开始就被设计成一个基于 eBPF 的轻量级事件追踪器。
  • Tracee 建立在 bcc 的基础上,并没有重写低级别的 BPF 接口。
  • Tracee 被设计成易于扩展,例如,在 tracee 中添加对新的系统调用的支持就像添加两行代码一样简单,在这里你可以描述系统调用的名称和参数类型。
  • 其他事件也被支持,比如内部内核函数。我们现在已经支持 cap_capable,我们正在增加对 security_bprm_check lsm 钩子的支持。由于 lsm 安全钩子是安全的战略要点,我们计划在不久的将来增加更多这样的钩子。

其实,从使用的场景上来说 Tracee 与 Falco 不是非 A 即 B 的功能,在 Tracee 也可以与 FalcoSideKick 进行集成,作为一个事件输入源使用。

从下面两者架构图的对比,我们也可以略微熟悉一二, Tracee 更加直接和简洁,规则引擎的维护也不是重点,而且规则引擎恰恰是 Falco 的重点。

Falco 的架构图如下:

而 Tracee 的架构图如下:

2. Tracee 的工作原理

Tracee 中的 tracee-ebpf 模块的核心能力包括: 事件跟踪(trace)、抓取(capture)和输出(output)三个能力。

tracee-ebpf 的核心能力在于底层 eBPF 程序抓取事件的能力,tracee-ebpf 默认实现了诸多的事件抓取功能,可以通过 trace -l 参看到底层支持的函数全集( 0.6.1 版本大概 390 个函数,格式如下:

$  sudo docker run --name tracee-only --rm --privileged --pid=host -v /lib/modules/:/lib/modules/:ro -v /usr/src:/usr/src:ro -v /tmp/tracee:/tmp/tracee -v /boot/:/boot tracee -l
System Calls: Sets: Arguments:
____________ ____ _________ read [syscalls fs fs_read_write] (int fd, void* buf, size_t count)
write [syscalls fs fs_read_write] (int fd, void* buf, size_t count)
open [default syscalls fs fs_file_ops] (const char* pathname, int flags, mode_t mode)
openat [default syscalls fs fs_file_ops] (int dirfd, const char* pathname, int flags, mode_t mode)
...
  • 第一列为系统调用函数名字;
  • 第二列为该函数归属为的子类(注可归属多个,比如 read 函数,归属于 syscalls/fs/fs_read_write 3 个子类,除了 fs 外,net 集合中也包含了许多的跟踪函数);
  • 第三列为该函数的原型,可以使用参数中的字段进行过滤,支持特定的运算,比如 == != 等常见的逻辑操作符,对于字符串也支持通配符操作;

这里简单介绍两个样例,更加详细的可以使用 tracee --trace help 命令查看。

  • --trace s=fs --trace e!=open,openat 跟踪 fs 集合中的所有事件,但是不包括 open,openat 两个函数;
  • --trace openat.pathname!=/tmp/1,/bin/ls 这里表示不跟踪 openat 事件中,pathname 为 /tmp/1,/bin/ls 的事件,注意这里的 openat.pathname 为跟踪函数名与函数参数的组合;

以上跟踪事件的过滤条件通过接口设置进内核中对应的 map 结构中,在完成过滤和事件跟踪以后,通过 perf_event 的方式上报到用户空间程序中,可以保存到奥文件后续进行处理,或者直接通过管道发送至 tracee-rule 进行解析和进行更高级别的上报,详细参见上一章节的架构图。

3. Tracee 功能测试

3.1 功能测试

测试前需要保证内核版本及相关条件满足最小要求:

  • 内核 >= 4.18,可选项启用了 BTF,BTF 启用可以通过 /boot/config* 文件检查 CONFIG_DEBUG_INFO_BTF 是否启用;(grep CONFIG_DEBUG_INFO_BTF /boot/config-xx-yyy)
  • Linux 内核头文件已经安装,Ubuntu/Debian/Arch/Manjaro 中为 linux-headers 包,CentOS/Fedora 中为 kernel-headers 和 kernel-devel 两个包;

如果内核启用了 BTF 功能,可以直接使用官方提供的镜像进行测试:

$ sudo docker run --name tracee --rm --privileged -it aquasec/tracee:latest trace

如果系统未启用 BTF 功能,则需要加载内核 /lib/modules/ 和 /usr/src 目录,并运行以下命令:

$ sudo docker run --name tracee --rm --privileged --pid=host -v  /boot:/boot:ro -v /lib/modules/:/lib/modules/:ro -v /usr/src:/usr/src:ro -v /tmp/tracee:/tmp/tracee -e TINI_SUBREAPER=true aquasec/tracee
Loaded signature(s): [TRC-1 TRC-2 TRC-3 TRC-4 TRC-5 TRC-6 TRC-7]

挂载 /boot 目录方便读取 /boot/config* 等相关文件,-e TINI_SUBREAPER=true 是为了让 tini 作为父进程进行子进程回收的能力。

在运行以后我们可以发现最后有一系列签名输出 TRC-1 TRC-2 TRC-3 TRC-4 TRC-5 TRC-6 TRC-7,这些签名代表了对应检测的选项。我们可以使用 --list 选项进行查看,结果如下:

# docker run --name tracee --rm --privileged --pid=host -v  /boot:/boot:ro -v /lib/modules/:/lib/modules/:ro -v /usr/src:/usr/src:ro -v /tmp/tracee:/tmp/tracee -e TINI_SUBREAPER=true aquasec/tracee --list
Loaded signature(s): [TRC-1 TRC-2 TRC-3 TRC-4 TRC-5 TRC-6 TRC-7]
ID NAME VERSION DESCRIPTION
TRC-1 Standard Input/Output Over Socket 0.1.0 Redirection of process's standard input/output to socket
TRC-2 Anti-Debugging 0.1.0 Process uses anti-debugging technique to block debugger
TRC-3 Code injection 0.1.0 Possible code injection into another process
TRC-4 Dynamic Code Loading 0.1.0 Writing to executable allocated memory region
TRC-5 Fileless Execution 0.1.0 Executing a process from memory, without a file in the disk
TRC-6 kernel module loading 0.1.0 Attempt to load a kernel module detection
TRC-7 LD_PRELOAD 0.1.0 Usage of LD_PRELOAD to allow hooks on process

使用 elfexec 进行测试:

# From https://github.com/abbat/elfexec/releases
$ wget https://github.com/abbat/elfexec/releases/download/v0.3/elfexec.x64.glibc.xz
$ chmod u+x elfexec.x64.glib && mv ./elfexec.x64.glibc ./elfexec
$ echo 'IyEvYmluL3NoCmVjaG8gIkhlbGxvISIK' | base64 -d|./elfexec
Hello!
$ echo 'IyEvYmluL3NoCmVjaG8gIkhlbGxvISIK' | base64 -d
#!/bin/sh
echo "Hello!"

上述命令就是将一个输出 echo hello 的脚本重定向到 elfexec 进行执行, 在上述命令运行后,输出以下信息:

# docker run --name tracee --rm --privileged --pid=host -v  /boot:/boot:ro -v /lib/modules/:/lib/modules/:ro -v /usr/src:/usr/src:ro -v /tmp/tracee:/tmp/tracee -e TINI_SUBREAPER=true aquasec/tracee
Loaded signature(s): [TRC-1 TRC-2 TRC-3 TRC-4 TRC-5 TRC-6 TRC-7] *** Detection ***
Time: 2021-09-10T09:10:25Z
Signature ID: TRC-5
Signature: Fileless Execution
Data: map[]
Command: elfexec
Hostname: VM-0-14-ubuntu

这里我们看到测试触发的签名为 TRC-5, 详细情况为 ”Fileless Execution“,命令为 ”elfexec“。

4. 源码编译 eBPF 程序

4.1 镜像方式编译

Tracee 支持我们自己基于系统编译 eBPF 程序,然后将编译后的 eBPF 字节码传递至 Docker 镜像进行运行。推荐 eBPF 程序编译通过 Docker 镜像进行,如果使用本机环境编译需要安装并保证 GNU Make >= 4.3 - clang >= 11。

推荐编译和运行基于 Ubuntu 系列的系统(Ubuntu 20.04),猜测 Tracee 的主要测试环境应该是在 Ubuntu 系列中,CentOS 系列测试偏少。

推荐 Ubuntu 20.04 版本,在 CentOS 5.4 内核中编译遇到不少问题,主要是环境差异导致,包括内核编译目录软连接,dockerfile 等问题,参见我提交的 pr

$ git clone --recursive https://github.com/aquasecurity/tracee.git
$ make bpf DOCKER=1 # --just-print 只是打印,编译完成后可以在 dist 目录中看到编译好的字节码程序
$ ls -hl dist/
total 7.8M
-rw-r--r-- 1 root root 3.1M Sep 10 17:22 tracee.bpf.5_4_132-1_el7_elrepo_x86_64.v0_6_1-1-gce65764.o
-rw-r--r-- 1 root root 4.7M Sep 10 17:22 tracee.bpf.core.o # 可以通过 TRACEE_BPF_FILE 环境变量指定我们需要加载的 eBPF 程序,这里使用目录 /tmp/tracee $ sudo docker run --name tracee --rm --privileged --pid=host -v /lib/modules/:/lib/modules/:ro -v /usr/src:/usr/src:ro -v /tmp/tracee:/tmp/tracee -e TRACEE_BPF_FILE=/tmp/tracee/tracee.bpf.core.o aquasec/tracee

如果编译 tracee-ebpf 我们也会发现,底层还是会依赖动态库,只是因为 tracee-ebpf 底层使用 cgo 机制使用 libbpf 库依赖的结果。

$ file tracee-ebpf/dist/tracee-ebpf| tr , '\n'
tracee-ebpf/dist/tracee-ebpf: ELF 64-bit LSB executable
x86-64
version 1 (SYSV)
dynamically linked (uses shared libs)
for GNU/Linux 3.2.0
BuildID[sha1]=5bd7dbfd0475f015e268e321476dfc928d06d950
not stripped $ # ldd tracee-ebpf/dist/tracee-ebpf
tracee-ebpf/dist/tracee-ebpf: /lib64/libc.so.6: version `GLIBC_2.22' not found (required by tracee-ebpf/dist/tracee-ebpf)
linux-vdso.so.1 => (0x00007ffe559d7000)
libelf.so.1 => /lib64/libelf.so.1 (0x00007f5d0c884000)
libz.so.1 => /lib64/libz.so.1 (0x00007f5d0c66e000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f5d0c452000)
libc.so.6 => /lib64/libc.so.6 (0x00007f5d0c084000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5d0ca9c000)

单独验证 tracee-ebpf 可以使用以下命令

$ sudo docker run --name tracee-only --rm --privileged --pid=host -v /lib/modules/:/lib/modules/:ro -v /usr/src:/usr/src:ro -v /tmp/tracee:/tmp/tracee -v /boot/:/boot tracee  --trace event=execve --output table-verbose --debug|more

4.2 编译错误处理

4.2.1 "bind": invalid mount path: './' mount path must be absolute

tracee-ebpf 使用 Docker-builder 路径加载报错如下:

Step 3/3 : WORKDIR /tracee
---> Using cache
---> 5e8a792b8117
Successfully built 5e8a792b8117
Successfully tagged tracee-builder:latest
docker run --rm -v /root/tracee/tracee-ebpf:./ -v /root/tracee/tracee-ebpf:/tracee/tracee-ebpf -w /tracee/tracee-ebpf --entrypoint make tracee-builder KERN_BLD_PATH=/usr/src/kernels/5.4.132-1.el7.elrepo.x86_64 KERN_SRC_PATH=build dist/tracee-ebpf VERSION=v0.6.1-1-gce65764
docker: Error response from daemon: invalid volume specification: '/root/tracee/tracee-ebpf:./': invalid mount config for type "bind": invalid mount path: './' mount path must be absolute.
See 'docker run --help'.
make: *** [dist/tracee-ebpf] Error 125

修改方式

+DOCKER_BUILDER_KERN_BLD ?= ``(if ``(shell readlink -f ``(KERN_BLD_PATH)),``(shell readlink -f ``(KERN_BLD_PATH)),``(KERN_BLD_PATH))
+DOCKER_BUILDER_KERN_SRC ?= ``(if ``(shell readlink -f ``(KERN_SRC_PATH)),``(shell readlink -f ``(KERN_SRC_PATH)),``(KERN_SRC_PATH))

主要差异点为系统不同,软链接的方式不同导致

CentOS

# ls -hl /lib/modules/5.4.132-1.el7.elrepo.x86_64/source
lrwxrwxrwx 1 root root 5 Jul 22 15:12 /lib/modules/5.4.132-1.el7.elrepo.x86_64/source -> build

Ubuntu

# ls -hl /lib/modules/5.4.0-42-generic/build
lrwxrwxrwx 1 root root 39 Jul 10 2020 /lib/modules/5.4.0-42-generic/build -> /usr/src/linux-headers-5.4.0-42-generic

4.2.2 单独生成 tracee-ebpf 镜像时,make: uname: Operation not permitted 等问题

$ make docker
docker build --build-arg VERSION=v0.6.1-1-gce65764 -t tracee:latest .
Sending build context to Docker daemon 2.116GB
Step 1/16 : ARG BASE=fat
Step 2/16 : FROM golang:1.16-alpine as builder
ARG BASE=fat FROM golang:1.16-alpine as builder
RUN apk --no-cache update && apk --no-cache add git clang llvm make gcc libc6-compat coreutils linux-headers musl-dev elfutils-dev libelf-static zlib-static
WORKDIR /tracee // ... make: uname: Operation not permitted
make: find: Operation not permitted
make: uname: Operation not permitted
make: /bin/sh: Operation not permitted
mkdir -p dist
make: mkdir: Operation not permitted
make: *** [Makefile:51: dist] Error 127
The command '/bin/sh -c make build VERSION=$VERSION' returned a non-zero code: 2
make: *** [docker] Error 2

该问题是 builder 基础镜像 golang:1.16-alpine 版本升级版本(alpine3.14 以后)导致的,明确指定为 golang:1.16-alpine3.13 即可:

-FROM golang:1.16-alpine as builder
+FROM golang:1.16-alpine3.13 as builder

4.2.3 failed to add kprobe 'p:kprobes/psecurity_file_open security_file_open': -17

异常退出后,再次运行可能会导致 ailed to create kprobe event: -17 的错误,错误的原因是使用了传统的 kprobe 方式,写入到 /sys/kernel/debug/tracing/kprobe_events 中,但是退出的时候未能够正常清理。

# docker run --name tracee --rm --privileged -v /lib/modules/:/lib/modules/:ro -v /usr/src:/usr/src:ro -v /tmp/tracee:/tmp/tracee -it aquasec/tracee:latest
2021/09/07 02:46:41 [INFO] : Enabled Outputs :
2021/09/07 02:46:41 [INFO] : Falco Sidekick is up and listening on port 2801
failed to add kprobe 'p:kprobes/psecurity_file_open security_file_open': -17
failed to create kprobe event: -17

如果出现错误可以通过 /sys/kernel/debug/tracing/kprobe_events 文件进行查看:

$ cat /sys/kernel/debug/tracing/kprobe_events
p:kprobes/psecurity_mmap_addr security_mmap_addr
p:kprobes/psecurity_file_mprotect security_file_mprotect
p:kprobes/psecurity_bprm_check security_bprm_check
p:kprobes/pcap_capable cap_capable
p:kprobes/psecurity_inode_unlink security_inode_unlink
p:kprobes/psecurity_file_open security_file_open

修复 sudo bash -c "echo""> /sys/kernel/debug/tracing/kprobe_events",参见 issue 447639

4.2.4 ‘err’ may be used uninitialized in this function

编译 libbpf 的时候可能报错,需要修改 Makefile 文件中的 CFLAGS ?= -g -O2 -Werror -Wall,删除 -Werror 即可。

btf_dump.c: In function ‘btf_dump_dump_type_data.isra.24’:
btf_dump.c:2266:5: error: ‘err’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
if (err < 0)
^
cc1: all warnings being treated as errors

4.2.5 Go 拉取包超时

// ...
GOOS=linux GOARCH=amd64 CC=clang CGO_CFLAGS="-I /tracee/tracee-ebpf/dist/libbpf/usr/include" CGO_LDFLAGS="/tracee/tracee-ebpf/dist/libbpf/libbpf.a" go build -tags netgo -v -o dist/tracee-ebpf \
-ldflags "-w -extldflags \"\"-X main.version=v0.6.1-1-gce65764"
go: github.com/aquasecurity/libbpfgo@v0.2.1-libbpf-0.4.0: Get "https://proxy.golang.org/github.com/aquasecurity/libbpfgo/@v/v0.2.1-libbpf-0.4.0.mod": dial tcp 142.251.42.241:443: i/o timeout
make: *** [Makefile:59: dist/tracee-ebpf] Error 1
make: *** [dist/tracee-ebpf] Error 2

添加代理执行 GOPROXY=https://goproxy.cn 即可。

$ docker run --rm -v /usr/src/kernels:/usr/src/kernels/ -v /root/tracee/tracee-ebpf:/tracee/tracee-ebpf -w /tracee/tracee-ebpf --entrypoint make tracee-builder DOCKER_BUILDER_KERN_SRC=/usr/src/kernels/5.4.132-1.el7.elrepo.x86_64 KERN_SRC_PATH=/lib/modules/5.4.132-1.el7.elrepo.x86_64/source KERN_BLD_PATH=/usr/src/kernels/5.4.132-1.el7.elrepo.x86_64 KERN_SRC_PATH=/usr/src/kernels/5.4.132-1.el7.elrepo.x86_64 dist/tracee-ebpf VERSION=v0.6.1-1-gce65764  GOPROXY=https://goproxy.cn

5. 参考

  1. Tracee: Tracing Containers with eBPF
  2. Tracee:如何使用 eBPF 来追踪容器和系统事件

eBPF 安全项目 Tracee 初探的更多相关文章

  1. 使用MyEclipse开发Java EE应用:EJB项目开发初探(下)

    你开学,我放价!MyEclipse线上狂欢继续!火热开启中>> [MyEclipse最新版下载] 三.EJB 3.x项目中的持久性支持 当创建EJB 3.x项目时,作为选项您可以添加JPA ...

  2. 使用MyEclipse开发Java EE应用:EJB项目开发初探(上)

    你开学,我放价!MyEclipse线上狂欢继续!火热开启中>> [MyEclipse最新版下载] 一.MyEclipse EJB开发工具 Enterprise Java Beans (EJ ...

  3. IDEA项目路径初探

    IDEA项目路径 普通Java项目 普通Java项目,标准目录结构src下的路径就是classpath类路径,每次编译都会将src目录下新增的类和资源文件打包进类路径. 如下图,类文件和配置文件都会被 ...

  4. opencv鼠标操作及GUI矩形绘画

    OpenCV的鼠标操作是通过一个中介函数配合回调函数来实现的.指定鼠标操作消息回调函数的函数为SetMouseCallback. void setMouseCallback(const string& ...

  5. GOICE项目初探

    GOICE项目初探         在图像拼接方面,市面上能够找到的软件中,要数MS的ICE效果.鲁棒性最好,而且界面也很美观.应该说有很多值得学习的地方,虽然这个项目不开源,但是利用现有的资料,也可 ...

  6. 从壹开始微服务 [ DDD ] 之七 ║项目第一次实现 & CQRS初探

    前言 哈喽大家周五好,我们又见面了,感谢大家在这个周五读我的文章,经过了三周的时间,当然每周两篇的速度的情况下,咱们简单说了下DDD领域驱动设计的第一部分,主要包括了,<项目入门DDD架构浅析& ...

  7. 《ASP.NET MVC 5 破境之道》:第一境 ASP.Net MVC5项目初探 — 第三节:View层简单改造

    第一境 ASP.Net MVC5项目初探 — 第三节:View层简单改造 MVC默认模板的视觉设计从MVC1到MVC3都没有改变,比较陈旧了:在MVC4中做了升级,好看些,在不同的分辨率下,也能工作得 ...

  8. 《ASP.NET MVC 5 破境之道》:第一境 ASP.Net MVC5项目初探 — 第二节:MVC5项目结构

    第一境 ASP.Net MVC5项目初探 — 第二节:MVC5项目结构 接下来,我们来看看,VS为我们自动创建的项目,是什么样子的? 可以通过菜单中[View]->[Solution Explo ...

  9. 《ASP.NET MVC 5 破境之道》:第一境 ASP.Net MVC5项目初探 — 第一节:运行第一个MVC5项目

    第一境 ASP.Net MVC5项目初探 — 第一节:运行第一个MVC5项目 创建一个MVC项目,是很容易的,大部分工作,VS都帮我们完成了.只需要按照如下步骤按部就班就可以了. 打开VS2017,选 ...

随机推荐

  1. 大数据学习(17)—— HBase表设计

    为啥要把表设计拿出来独立成章?因为我觉得像我这样搞了很多年Java后端开发的技术人员,在学习HBase的时候,会受到关系型数据库3NF.BCNF的影响.事实上,数据库范式在HBase里完全没用,必须转 ...

  2. vulnhub-DC:7靶机渗透记录

    准备工作 在vulnhub官网下载DC:7靶机DC: 7 ~ VulnHub 导入到vmware,设置成NAT模式 打开kali准备进行渗透(ip:192.168.200.6) 信息收集 已经知道了靶 ...

  3. SQL语句(六)分页查询和联合查询

    目录 一.分页查询 语法格式 应用 二.联合查询 语法和作用 特点 应用 UNION和UNION ALL的区别 一.分页查询 语法格式 SELECT 查询列表 FROM 表 WHERE ... GRO ...

  4. SQL语句(四)联表查询

    目录 一.关联查询的分类 按年代分 按功能分 二.sql92语法的连接 语法 1. 简单应用 2. 为表起别名 3. 加入筛选 4. 加入分组 5. 三表连接 6. 非等值连接 7. 自连接 三.sq ...

  5. docker报错Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

    docker报错Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon run ...

  6. Vulhub-DC-1靶场

    前言: DC-1靶场是Vulhub系一款渗透测试的实战靶场,拥有五个Flag.本篇博客讲述了如何拿去这五个Flag,并详细描述其中的注意点. 实验环境: 虚拟机环境:virtualbox 虚拟机1:D ...

  7. ffuf 基础食用指南

    PS: 1. 下文出现的某些字典 有可能是因为摆出效果 我自己瞎搞得字典 2. 分享一些好的工具 3. 其实Wfuzz也很好用的 4. 很早之前就在语雀写过Wfuzz和ffuf的笔记 但是一直没有公开 ...

  8. Crash course statistics

    Crash course statistics 01什么是统计学 描述性统计(Descriptive statistics) 推理统计可以得出之外的,基于"样本"的推论统计学来估计 ...

  9. 51单片机—LCD1602显示模块

    文章目录 - 什么是LCD1602 - 如何操作LCD1602 - 上代码 - 什么是LCD1602 LCD:Liquid Crystal Display-液晶显示器,简称LCD,其主要显示原理是以电 ...

  10. Linux+Apache+Mysql+PHP简单的测试环境搭建

    系统版本为:Linux localhost.localdomain 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x ...