checksec项目开源 https://github.com/slimm609/checksec.sh
checksec是一个用于检测文件、进程、内核安全特性的开源项目,开源在使用shell脚本编写,主要应用在Linux平台。
根据项目主页描述,checksec项目最早由漏洞挖掘专家Tobias Klein编写,目前该项目主要由slimm609、teoberi等人维护。C语言重写项目开源 https://github.com/fuxxcss/checksecc建议下载main版本
根据项目主页描述,checksecc是checksec的C语言重写版,并给出了详细的安装和使用教程。项目全部由C语言和Makefile编写,适合C语言的初学者学习。
本章节将简要分析checksec检测文件的原理,重点分析使用C语言重写该项目的逻辑。下文以checksec.sh和checksecc来区分二者。
checksec.sh文件检测
checksec.sh文件检测有以下五个用法。
## Checksec Options
--file={
file}
--dir={
directory}
--listfile={
text file with one file per line}
--fortify-file={
executable-file}
--extended
file、dir、listfile选项的逻辑都是检测文件、文件列表的基础安全特性,最新版本支持以下11种。
- RELRO:got表只读保护,有No、Partial和Full三种情况,针对延迟绑定特性进行保护。
- STACK CANARY:栈中敏感数据防覆写保护。
- NX:代码不可写,数据不可执行。
- PIE:位置无关代码,配合ASLR阻止ROP攻击。
- RPATH、RUNPATH:文件是否使用了这种危险的环境变量。
- Symbols:符号信息。
- FORTIFY、Fortified、Fortifiable:危险函数是否被加固。
- FILE:被检测文件名。
fortify-file选项是对危险函数加固情况的具体说明,为了性能考虑,编译时默认不启用加固。该选项包含以下信息。
* FORTIFY_SOURCE support available (libc) # libc是否支持加固
* Binary compiled with FORTIFY_SOURCE support # 文件是否启用加固
# 对应函数
------ EXECUTABLE-FILE ------- . -------- LIBC --------
FORTIFY-able library functions | Checked function names
-------------------------------------------------------
fdelt_chk | __fdelt_chk
read | __read_chk
syslog_chk | __syslog_chk
fprintf_chk | __fprintf_chk
vsnprintf_chk | __vsnprintf_chk
fgets | __fgets_chk
strncpy | __strncpy_chk
snprintf_chk | __snprintf_chk
memset | __memset_chk
strncat_chk | __strncat_chk
memcpy | __memcpy_chk
fread | __fread_chk
sprintf_chk | __sprintf_chk
# 数量的总结
SUMMARY:
* Number of checked functions in libc
* Total number of library functions in the executable
* Number of FORTIFY-able functions in the executable
* Number of checked functions in the executable
* Number of unchecked functions in the executable
extended扩展选项在基础特性上增加了3个特性。
- SELFRANDO:Tor网络开发的,用于内存地址随机化。
- Clang CFI:Clang编译器插桩选项,用于控制流完整性检测。
- SafeStack:更强大的栈保护策略。
checksec.sh文件检测原理
checksec.sh检测文件的核心函数在源码 src/functions/filecheck.sh 中。基本逻辑是使用readelf工具对文件的程序头表、动态节、节头表、函数名进行字符匹配,来判断该文件是否开启了某一安全特性。
以检测RELRO为例,使用readelf检测文件的程序头表,是否有GNU_RELRO。( GNU_RELRO仅在加载文件时进行解析,而不映射在段中 )如果编译器配置了GNU_RELRO,则说明启用了RELRO保护策略,需要进一步判断是Partial还是Full。接着通过匹配动态节的输出信息,如果有BIND_NOW标志,则说明文件需要在加载时绑定,而非延迟绑定,即RELRO Full策略。
filecheck() {
# check for RELRO support
if [[ $(${
readelf} -l "${1}" 2> /dev/null) =~ "no program headers" ]]; then
echo_message '\033[32mN/A \033[m ' 'N/A,' '<file relro="n/a"' " \"${1}\": { \"relro\":\"n/a\","
elif ${readelf} -l "${1}" 2> /dev/null | grep -q 'GNU_RELRO'; then
if ${readelf} -d "${1}" 2> /dev/null | grep -q 'BIND_NOW' || ! ${readelf} -l "${1}" 2> /dev/null | grep -q '\.got\.plt'; then
echo_message '\033[32mFull RELRO \033[m ' 'Full RELRO,' '<file relro="full"' " \"${1}\": { \"relro\":\"full\","
else
echo_message '\033[33mPartial RELRO\033[m ' 'Partial