Linux Pwn - 安全机制

Linux下的安全机制有:

  • Stack Canaries
  • NX
  • ASLR/PIE
  • FORTIFY_SOURCE
  • RELRO

Stack Canaries

Linux平台上的安全cookie(与Windows上安全cookie具有相同的作用),用于缓解缓冲区溢出

Canaries通常可以分为三类:

种类 说明
Terminator Canaries Canaries的低位被设置为\x00,可以用来截断字符串
Random Canaries 在程序初始化时生成一个随机值,并保存一份备份在一个相对安全的地方(TLS)
在Linux中,TLS在fs指向的位置(x64),而在x86下则是gs
Canaries值位于fs:[0x28]gs:[0x14]
Random XOR Canaries 在Random Canaries基础上增加了异或操作

checksec.sh检查如下:

1
2
3
4
5
if ${readelf} -s "${1}" 2>/dev/null | grep -Eq '__stack_chk_fail|__intel_security_cookie'; then
echo_message '\033[32mCanary found \033[m ' 'Canary found,' ' canary="yes"' '"canary":"yes",'
else
echo_message '\033[31mNo canary found\033[m ' 'No Canary found,' ' canary="no"' '"canary":"no",'
fi

No-eXecute

相当于Windows平台上的DEP(数据执行保护),NX的实现由软件和硬件共同完成

  • 硬件层:利用CPU的NX位,对相应页表项中的第63位进行设置
    • NX=1,不可知性
    • NX=0,可执行
  • 软件层面:需要操作系统支持NX以配置页表,涉及相关API
    • Windows:VirtualAllocVirtualProtect
    • Linux:mmapmprotect

checksec.sh检查如下:

1
2
3
4
5
6
7
8
9
if ${readelf} -l "${1}" 2>/dev/null | grep -q 'GNU_STACK'; then
if ${readelf} -l "${1}" 2>/dev/null | grep 'GNU_STACK' | grep -q 'RWE'; then
echo_message '\033[31mNX disabled\033[m ' 'NX disabled,' ' nx="no"' '"nx":"no",'
else
echo_message '\033[32mNX enabled \033[m ' 'NX enabled,' ' nx="yes"' '"nx":"yes",'
fi
else
echo_message '\033[31mNX disabled\033[m ' 'NX disabled,' ' nx="no"' '"nx":"no",'
fi

ASLR和PIE

ASLR(地址空间随机化),在Linux上ASLR的全局配置为/proc/sys/kernel/randomize_va_space,有以下三种情况:

  • 0,表示关闭ASLR
  • 1,表示部分开启(mmap的基址,stack和vdso页面随机化)
  • 2,表示完全开启(增加heap随机化)

另外,在PIE(位置无关可执行文件)开启下,相当于可执行文件也支持重定位,即每次执行时的装载地址都会不同

ASLR Executable PLT Heap Stack Shared Libaries
0 × × × × ×
1 × × ×
2 × ×
2 + PIE

checksec.sh检查如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
if ${readelf} -h "${1}" 2>/dev/null | grep -q 'Type:[[:space:]]*EXEC'; then
echo_message '\033[31mNo PIE \033[m ' 'No PIE,' ' pie="no"' '"pie":"no",'
elif ${readelf} -h "${1}" 2>/dev/null | grep -q 'Type:[[:space:]]*DYN'; then
if ${readelf} -d "${1}" 2>/dev/null | grep -q 'DEBUG'; then
echo_message '\033[32mPIE enabled \033[m ' 'PIE enabled,' ' pie="yes"' '"pie":"yes",'
else
echo_message '\033[33mDSO \033[m ' 'DSO,' ' pie="dso"' '"pie":"dso",'
fi
elif ${readelf} -h "${1}" 2>/dev/null | grep -q 'Type:[[:space:]]*REL'; then
echo_message '\033[33mREL \033[m ' 'REL,' ' pie="rel"' '"pie":"rel",'
else
echo_message '\033[33mNot an ELF file\033[m ' 'Not an ELF file,' ' pie="not_elf"' '"pie":"not_elf",'
fi

FORTIFY_SOURCE

FORITFY_SOURCE机制相当于glibc的一个安全补丁,可为字符串操作函数提供轻量级的缓冲区溢出攻击和格式化字符串攻击检查。即会将存在隐患的函数替换为更加安全的函数,这些更加安全的函数位于glibc源码的debug目录下

此机制在Unbuntu 16.04(GCC-5.4.0)中是默认关闭的。当指定了O1优化则开启FORTIFY_SOURCE等级1,对于等级2需要手动开启

  • -D_FORTIFY_SOURCE=1,开启缓冲区溢出攻击检查
  • -D_FORTIFY_SOURCE=2,开启缓冲区溢出攻击和格式化字符串攻击检查

checksec.sh检查如下:

1
2
3
4
5
if grep -q '_chk$' <<<"$FS_functions"; then
echo_message '\033[32mYes\033[m' 'Yes,' ' fortify_source="yes" ' '"fortify_source":"yes",'
else
echo_message "\033[31mNo\033[m" "No," ' fortify_source="no" ' '"fortify_source":"no",'
fi

RELRO

RELRO机制为了解决要吃绑定的安全问题而出现,RELOR有两种形式:

  • Partial RELRO
    • 一些段(.dynamic.got等)在初始化后被设置为只读
    • Ubuntu 16.04 GCC-5.4.0默认开启
  • Full RELRO
    • 禁止延迟绑定,.got.plt段将会合并到.got段中,并且直接初始化为目标函数地址
    • link_mapdl_runtime_resolve不会被装载

checksec.sh检查如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if ${readelf} -l "${1}/exe" 2>/dev/null | grep -q 'Program Headers'; then
if ${readelf} -l "${1}/exe" 2>/dev/null | grep -q 'GNU_RELRO'; then
if ${readelf} -d "${1}/exe" 2>/dev/null | grep -q 'BIND_NOW'; then
echo_message '\033[32mFull RELRO \033[m ' 'Full RELRO,' ' relro="full"' '"relro":"full",'
else
echo_message '\033[33mPartial RELRO\033[m ' 'Partial RELRO,' ' relro="partial"' '"relro":"partial",'
fi
else
echo_message '\033[31mNo RELRO \033[m ' 'No RELRO,' ' relro="no"' '"relro":"no",'
fi
else
echo -n -e '\033[31mPermission denied (please run as root)\033[m\n'
exit 1
fi
打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2021 lzeroyuee
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信