rambo@matrix:~$ whoami
rambo
rambo@matrix:~$ cat /proc/sys/vm/mmap_min_addr
65536
#include <sys/mman.h>
#include <string.h>
#include <stdio.h>
int main(){
char hello = "hello, world";
mmap(0, 4096,PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS ,-1, 0);
printf("mmap succeeded!n");
memcpy(0, hello, sizeof(hello));
return 0;
}
rambo@matrix:~$ gcc -o mmap_test test.c -w
rambo@matrix:~$ ./mmap_test
Segmentation fault (core dumped)
rambo@matrix:~$ sudo sh -c "echo 0 > /proc/sys/vm/mmap_min_addr"
rambo@matrix:~$ ./mmap_test
mmap succeeded!
#include <stdio.h>
int main(){
char hello[20];
scanf("%s", hello);
printf("Variable address: %xn", hello);
printf("main func's address: %xn", (void *)main);
return 0;
}
rambo@matrix:~$ gcc -no-pie -o aslr_test aslr_test.c -w
rambo@matrix:~$ ./aslr_test
hello
Variable address: 7549f420
main func's address: 4005c7
rambo@matrix:~$ ./aslr_test
hello
Variable address: d724c8a0
main func's address: 4005c7
rambo@matrix:~$ sudo sh -c "echo 0 > /proc/sys/kernel/randomize_va_space"
rambo@matrix:~$ ./aslr_test
hello
Variable address: ffffe3f0
main func's address: 4005c7
rambo@matrix:~$ ./aslr_test
hello
Variable address: ffffe3f0
main func's address: 4005c7
rambo@matrix:~$ sudo cat /proc/kallsyms | grep 'T startup_64'
ffffffffb5e00000 T startup_64
rambo@matrix:~$ sudo init 6 # 重启
rambo@matrix:~$ sudo cat /proc/kallsyms | grep 'T startup_64'
ffffffff9fc00000 T startup_64
GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0 nokaslr"
rambo@matrix:~$ sudo update-grub
Sourcing file `/etc/default/grub'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-4.15.0-101-generic
Found initrd image: /boot/initrd.img-4.15.0-101-generic
Found linux image: /boot/vmlinuz-4.15.0-96-generic
Found initrd image: /boot/initrd.img-4.15.0-96-generic
done
rambo@matrix:~$ sudo cat /proc/kallsyms | grep 'T startup_64'
ffffffff81000000 T startup_64
commit_creds(prepare_creds());
/*
* We show kallsyms information even to normal users if we've enabled
* kernel profiling and are explicitly not paranoid (so kptr_restrict
* is clear, and sysctl_perf_event_paranoid isn't set).
*
* Otherwise, require CAP_SYSLOG (assuming kptr_restrict isn't set to
* block even that).
*/
int kallsyms_show_value(void)
{
switch (kptr_restrict) {
case 0:
if (kallsyms_for_perf())
return 1;
/* fallthrough */
case 1:
if (has_capability_noaudit(current, CAP_SYSLOG))
return 1;
/* fallthrough */
default:
return 0;
}
}
static inline int kallsyms_for_perf(void)
{
#ifdef CONFIG_PERF_EVENTS
extern int sysctl_perf_event_paranoid;
if (sysctl_perf_event_paranoid <= 1)
return 1;
#endif
return 0;
}
rambo@matrix:~$ whoami
rambo
rambo@matrix:~$ cat /proc/sys/kernel/kptr_restrict
0
rambo@matrix:~$ cat /proc/sys/kernel/perf_event_paranoid
3
rambo@matrix:~$ cat /proc/kallsyms | tail -n 2
0000000000000000 t cleanup_module [pata_acpi]
0000000000000000 r __mod_pci__pacpi_pci_tbl_device_table [pata_acpi]
rambo@matrix:~$ sudo sh -c "echo 0 > /proc/sys/kernel/perf_event_paranoid"
rambo@matrix:~$ cat /proc/kallsyms | tail -n 2
ffffffffc008141d t cleanup_module [pata_acpi]
ffffffffc0082080 r __mod_pci__pacpi_pci_tbl_device_table [pata_acpi]
那么,设置kptr_restrict限制有什么意义呢?这主要是为了防止内核符号地址被非特权用户恶意利用——例如,用来绕过KASLR。由于KASLR在系统启动时对内核基址做了随机化处理,攻击者在不进行暴力破解的情况下很难命中内核符号的正确地址,继而无法在Exploit中应用关键内核函数去实现权限提升等操作。如果作为非特权用户的攻击者能够借助/proc/kallsyms等方式获得有效的内核符号地址,KASLR就被绕过了。
例如,攻击者能够借此直接获得权限提升所需的关键内核函数地址:
rambo@matrix:~$ cat /proc/kallsyms | grep 'T commit_creds'
ffffffff8b4b47c0 T commit_creds
rambo@matrix:~$ cat /proc/kallsyms | grep 'T prepare_kernel_cred'
ffffffff8b4b4b90 T prepare_kernel_cred
dmesg_restrict:限制内核日志暴露以防绕过KASLR
dmesg_restrict用来决定是否限制非特权用户使用dmesg查看内核日志缓冲区中的消息。其值为0时,非特权用户对内核日志的查看将不受限制;值为1时,只有具有CAP_SYSLOG特权的用户才能查看内核日志[2]。
例如,在dmesg_restrict值为0时(配置文件为/proc/sys/kernel/dmesg_restrict),非特权用户rambo能够读取到内核日志:
rambo@matrix:~$ whoami
rambo
rambo@matrix:~$ grep CapEff /proc/self/status
CapEff: 0000000000000000
rambo@matrix:~$ dmesg | tail -n 3
[4322561.736000] docker0: port 1(vethc613760) entered disabled state
[6418769.946155] audit: type=1305 audit(1593338728.486:87): audit_rate_limit=512 old=512 auid=4294967295 ses=4294967295 res=1
[6418769.946401] audit: type=1305 audit(1593338728.486:88): audit_backlog_limit=2048 old=2048 auid=4294967295 ses=4294967295 res=1
rambo@matrix:~$ sudo sh -c "echo 1 > /proc/sys/kernel/dmesg_restrict"
rambo@matrix:~$ dmesg | tail -n 3
dmesg: read kernel buffer failed: Operation not permitted
rambo@matrix:~$ sudo sh -c "grep CapEff /proc/self/status"
CapEff: 0000003fffffffff
rambo@matrix:~$ capsh --decode=0000003fffffffff | grep "cap_syslog"
0x0000003fffffffff=cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read
rambo@matrix:~$ sudo dmesg | tail -n 3
[4322561.736000] docker0: port 1(vethc613760) entered disabled state
[6418769.946155] audit: type=1305 audit(1593338728.486:87): audit_rate_limit=512 old=512 auid=4294967295 ses=4294967295 res=1
[6418769.946401] audit: type=1305 audit(1593338728.486:88): audit_backlog_limit=2048 old=2048 auid=4294967295 ses=4294967295 res=1
dmesg | grep 'Freeing SMP'
Freeing SMP alternatives memory: 32K (ffffffff9e309000 - ffffffff9e311000)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 2b3bf67..3f63973 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -6508,8 +6508,8 @@ unsigned long free_reserved_area(void *start, void *end, int poison, char *s)
}
if (pages && s)
- pr_info("Freeing %s memory: %ldK (%p - %p)n",
- s, pages << (PAGE_SHIFT - 10), start, end);
+ pr_info("Freeing %s memory: %ldKn",
+ s, pages << (PAGE_SHIFT - 10));
return pages;
}
rambo@matrix:~$ dmesg | grep 'Freeing SMP'
[ 0.004000] Freeing SMP alternatives memory: 36K
rambo@matrix:~$ cat /proc/cpuinfo | grep -E "smep|smap"
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology cpuid tsc_known_freq pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single pti ibrs ibpb fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 arat
参考文献
本专题其他文章:
• 容器逃逸技术概览
• 容器逃逸成真:从CTF解题到CVE-2019-5736漏洞挖掘分析
星云实验室专注于云计算安全、解决方案研究与虚拟化网络安全问题研究。基于IaaS环境的安全防护,利用SDN/NFV等新技术和新理念,提出了软件定义安全的云安全防护体系。承担并完成多个国家、省、市以及行业重点单位创新研究课题,已成功孵化落地绿盟科技云安全解决方案
往期回顾
本公众号原创文章仅代表作者观点,不代表绿盟科技立场。所有原创内容版权均属绿盟科技研究通讯。未经授权,严禁任何媒体以及微信公众号复制、转载、摘编或以其他方式使用,转载须注明来自绿盟科技研究通讯并附上本文链接。
关于我们
绿盟科技研究通讯由绿盟科技创新中心负责运营,绿盟科技创新中心是绿盟科技的前沿技术研究部门。包括云安全实验室、安全大数据分析实验室和物联网安全实验室。团队成员由来自清华、北大、哈工大、中科院、北邮等多所重点院校的博士和硕士组成。
绿盟科技创新中心作为“中关村科技园区海淀园博士后工作站分站”的重要培养单位之一,与清华大学进行博士后联合培养,科研成果已涵盖各类国家课题项目、国家专利、国家标准、高水平学术论文、出版专业书籍等。
我们持续探索信息安全领域的前沿学术方向,从实践出发,结合公司资源和先进技术,实现概念级的原型系统,进而交付产品线孵化产品并创造巨大的经济价值。
长按上方二维码,即可关注我们
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论