Fuzzing start
不可视境界线最后变动于:2023年4月29日 晚上
资源的查
- afl_training: https://github.com/mykter/afl-training
- Fuzzing101: https://github.com/antonio-morales/Fuzzing101
- AFL源码分析 | AFL技术实现分析 | AFL的LLVM_mode |
- fuzz_in_depth : 还挺多东西, 主要就是三步走.
Fuzzer: syzkaller
- KASAN: kernel address sanitizer - kernel doc
- Fault Injection : 用于模拟故障情况并观察系统的响应和行为以发现和解决问题。它主要通过在内核代码中添加注释或编写额外的代码来实现。这些注释和代码描述了模拟故障的位置、类型和参数,被称为FIB块(Fault Injection Block)
- Golang by e.g. | Lang Spec | https://pkg.go.dev/std
- A method is a function with a receiver.
install
- 下载linux kernel, 直接github找到对应tag下载zip. 如果是拉取git仓库那就太庞大了, 所有的历史记录都给拉下来, 切换版本是方便了还完全没必要.
参照文档即可.遇到一些坑记录一下.apt install make gcc flex bison libncurses-dev libelf-dev libssl-dev
- 设置kernel config:
1 |
|
- 手动设置.config文件:
1 |
|
make olddefconfig
make -j $(nproc)
本机6个core. 但是链接的时候内存峰值给我用到了9G, 原本2G的kali撑出OOM来…..编译新版本的kernel没有遇到源码问题, 挺不错- 接下来构造一下文件系统. 执行一个使用debootstrap的script, 坑点在于这个命令会连外网装上一些packet, 需要梯子: 把create-image.sh中那一行前面加上proxychains即可.
这个脚本还可以切换成其他的distribution. 这里下载的默认是bullseye. 还有其他功能详见文档.
1 |
|
1 |
|
- qemu安装后的启动脚本
- 看到
hostfwd
选项, 这是将主机10021端口映射到虚拟机的22号ssh端口上. 所以在下面ssh命令中指定了-p 10021
. - 注意到append中有一个
net.ifnames=0
, 这是禁用了Predictable Network Interface Names, 否则会根据设备来生成接口名称, 而非传统的ethX. 在create-image.sh
中指定了ethX的形式, 所以在first.ctg中也要在-append参数中加上这么一行. 更多…
- 看到
1 |
|
- 但是先别急着启动, 因为我发现这没有init文件. 复制一个现成的. 然后又发现里面的sh不能接受
poweroff -d
这个参数. 改成简单的poweroff -f
.
这里用_mnt
的原因是vmware当成共享文件夹专用地, 不让我在这里make文件夹…….暂时不改了.
我还没搞清init中一些命令是否是必要的. 反正去掉也能用.
1 |
|
1 |
|
- ssh连接必须能成功:
1 |
|
- kill:
kill $(cat vm.pid)
- 接下来是SETUP syzkaller. 由于是go开发的, 先安装golang.
1 |
|
- 编译一下用我了20G内存. 正常谁给这么多啊???整完又改成4G了.
- 编译好之后出现了
syzkaller/bin
文件夹, 添加到PATH下. 然后随便哪里新建文件夹workdir, 再新建个json用作设置.
1 |
|
- 写个简单小脚本来自动替换上面的内容. (又看了一会儿的文档)
1 |
|
- 然后直接运行即可
1 |
|
配置成功!
感觉细节也是不少, 没别人说的那么容易.
Useage
Coverage
use sanitizer coverage (tracing mode) and KCOV for coverage collection.
Coverage is based on tracing
coverage points
inserted into the object code by the compiler. A coverage point generally refers to a basic block of code or a CFG edge (this depends on the compiler and instrumentation mode used during build, e.g. forLinux
andclang
the default mode is CFG edges, while forgcc
the default mode is basic blocks).Note that coverage points are inserted by the compiler in the middle-end after a significant number of transformation and optimization passes.
Linux specific coverage information. 主要是利用kcov的输出(debugfs), 然后接到binutils转换成
readelf解出每个段的虚存偏移
nm解出所有代码段的符号地址和大小. 16位对齐向上取整.
objdump解出
__sanitizer_cov_trace_pc
返回的值, 用来和kcov返回的PC值进行对比. 通过反汇编可以得到trace call的起始地址, 也就是the start address of executable blocks.addr2line映射 kcov导出的和objdump解析的PC值 源代码文件和行
The final goal is to have a hash table of frames where key is a PC and value is a frame array consisting of a following information:
PC
- 64bit program counter value (same as key)Func
- function name to which the frame belongsFile
- file where function/frame code is locatedLine
- Line in a file to which program counter mapsInline
- boolean inlining information
Multiple frames can be linked to a single program counter value due to inlining.
Creating report
Once the database of the frames and function address ranges is created the next step is to determine the program coverage. Each program is represented here as a series of program counter values. The resulting coverage is not line based but the basic block based. The end result is stored in the
file
struct containing the following information:lines
- lines covered in the filetotalPCs
- total program counters identified for this filecoveredPCs
- the program counters that were executed in the program runtotalInline
- total number of program counters mapped to inlined framescoveredInline
- the program counters mapped to inlined frames that were executed in the program run