我现在正在阅读 Shellcoder 手册:发现和利用安全漏洞,第二版。
在第二章中考虑了像这样的简单缓冲区溢出问题(C代码):
int main () {
int array[5];
int i;
for (i = 0; i <= 255; i++ ) {
array[i] = 10;
}
}
作者编译代码cc
并执行它:
shellcoders@debian:~/chapter_2$ cc buffer2.c
shellcoders@debian:~/chapter_2$ ./a.out
Segmentation fault (core dumped)
然后查看了写入的核心转储gdb
:
shellcoders@debian:~/chapter_2$ gdb -q -c core
Program terminated with signal 11, Segmentation fault.
#0 0x0000000a in ?? ()
(gdb)
问题是我的情况下还没有写入核心转储。我只有一条消息:zsh: segmentation fault ./a.out
。
我在 VirtualBox 中使用 Kali 2021.4a。我曾尝试更改默认 shell,chsh -s /bin/bash
但它没有改变任何内容,并且终端保持打开状态zsh
。
如何在错误时写入核心转储?看起来它应该是与可执行文件写入同一目录中的文件。
答案1
首先,您需要使用ulimit
命令(在 bash 或 zsh 中)检查限制内的核心文件大小。
# ulimit -c
0
如果它为零,则需要增加它。例如,将其增加到无限:
# ulimit -c unlimited
# ulimit -c
unlimited
其次,您需要检查 coredump 是在哪里创建的。在较旧的发行版上,默认值通常是 CWD 中名为“core”的文件。这可能是本书撰写时的默认设置。
# /sbin/sysctl kernel.core_pattern
kernel.core_pattern = core
然而,如今在大多数发行版上,情况已不再如此。今天通常使用以下方式生成核心systemd-coredump(8)
。
# /sbin/sysctl kernel.core_pattern
kernel.core_pattern = |/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %e
来自男人systemd-coredump(8)
:
默认情况下,systemd-coredump 会将核心转储记录到日志中,如果可能的话还包括回溯,并将核心转储(进程内存内容的映像)本身存储在外部文件中 /var/lib/systemd/coredump。
您可以在该目录中找到核心转储,也可以使用coredumpctl
列出这些(您可能需要 sudo 或以 root 身份运行):
# coredumpctl list
TIME PID UID GID SIG PRESENT EXE
Wed 2022-01-26 12:53:06 IST 10347 111 222 11 * /tmp/a.out
*
“PRESENT”下方的 表示已创建核心转储文件。
您可以使用以下命令查看(压缩的)核心转储的位置coredumpctl info <pid>
:
# coredumpctl info 10347 |grep Coredump
Coredump: /var/lib/systemd/coredump/core.a\x2eout.111.1bd8e22a25e844f1b03a87d378b4ed9b.10347.1643194386000000.xz
您可以使用xz
命令解压缩该文件:
# xz --decompress --stdout '/var/lib/systemd/coredump/core.a\x2eout.111.1bd8e22a25e844f1b03a87d378b4ed9b.10347.1643194386000000.xz' > core
或者使用以下命令将核心转储到某个目的地。
# coredumpctl -o core dump 10347
这些命令中的任何一个都会创建该文件:
# gdb -q -c core
[New LWP 10347]
Core was generated by `/tmp/a.out'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x0000000af7a56725 in ?? ()
答案2
根据man core
,有多种情况不生成核心转储文件:
* The process does not have permission to write the core file.… * A (writable, regular) file with the same name as would be used for the core dump already exists, but there is more than one hard link to that file. * The filesystem where the core dump file would be created is full; or has run out of inodes; or is mounted read-only; or the user has reached their quota for the filesystem. * The directory in which the core dump file is to be created does not exist. * The RLIMIT_CORE (core file size) or RLIMIT_FSIZE (file size) resource limits for the process are set to zero;… * The binary being executed by the process does not have read permission enabled.… * The process is executing a set-user-ID (set-group-ID) program that is owned by a user (group) other than the real user (group) ID of the process, or the process is executing a program that has file capabilities… * /proc/sys/kernel/core_pattern is empty and /proc/sys/kernel/core_uses_pid contains the value 0. * (Since Linux 3.7) The kernel was configured without the CONFIG_COREDUMP option.
因此,您应该首先检查这些条件,特别是最有可能的最后一个:CONFIG_COREDUMP 内核选项。
顺便说一句,还请注意:
在使用 systemd(1) 作为 init 框架的系统上,核心转储可能会放置在由 systemd(1) 确定的位置。
在许多实现下,它对应于某个/var/lib/systemd
子目录。