clone
根据逆出来的代码
pid = clone((int (*)(void *))fn, &std::__throw_length_error, 0x10000011, 0);
0x110000011对应
#define CLONE_NEWUSER 0x10000000 /* New user namespace */
#define SCHED_FIFO 1
#define SCHED_RR 2
linux源码位于include/uapi/linux/sched.h
chroot
chroot可以用了保护程序,限制攻击者在某目录下执行一些命令。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sched.h>
#include <sys/wait.h>
// son function test
void sub_func_df()
{
pid_t m_pid = getpid();
printf("[*]pid is %d\n", m_pid);
printf("[*]start sub call ls\n");
system("ls");
printf("[*] sub process over\n");
exit(0);
}
int main(int argc, char *argv[])
{
pid_t df_pid = getpid();
pid_t sub_pid;
int sub_status;
printf("[+]father pid is 0x%x\n", df_pid);
sub_pid = fork();
if(sub_pid<0)
{
perror("fork sub pid");
exit(1);
}
if(!sub_pid)
{
chdir("jail");
system("pwd");
if(chroot("./") != 0)
{
perror("chroot");
exit(1);
}
sub_func_df();
}
waitpid(sub_pid, &sub_status, 0);
printf("[+]start parent system call pwn\n");
system("pwd");
return 0;
}
写了一段代码测试。
输出结果如下
deadfish@ubuntu:~/Pwn/Core$ sudo ./ptrace_demo
[+]father pid is 0x156f
/home/deadfish/Pwn/Core/jail
[*]pid is 5488
[*]start sub call ls
[*] sub process over
[+]start parent system call pwn
/home/deadfish/Pwn/Core
可以得知子进程在chroot之前能够执行system,但是chroot之后不能执行system函数。
下面是chroot的说明
DESCRIPTION
chroot() changes the root directory of the calling process to that specified in path. This directory will be used for pathnames begin‐
ning with /. The root directory is inherited by all children of the calling process.
Only a privileged process (Linux: one with the CAP_SYS_CHROOT capability) may call chroot().
This call changes an ingredient in the pathname resolution process and does nothing else. In particular, it is not intended to be used
for any kind of security purpose, neither to fully sandbox a process nor to restrict filesystem system calls. In the past, chroot()
has been used by daemons to restrict themselves prior to passing paths supplied by untrusted users to system calls such as open(2).
The easiest way to do that is to chdir(2) to the to-be-moved directory, wait for it to be moved out, then open a path like
../../../etc/passwd.
A slightly trickier variation also works under some circumstances if chdir(2) is not permitted. If a daemon allows a "chroot direc‐
tory" to be specified, that usually means that if you want to prevent remote users from accessing files outside the chroot directory,
you must ensure that folders are never moved out of it.
This call does not change the current working directory, so that after the call '.' can be outside the tree rooted at '/'. In particu‐
lar, the superuser can escape from a "chroot jail" by doing:
mkdir foo; chroot foo; cd ..
This call does not close open file descriptors, and such file descriptors may allow access to files outside the chroot tree.
大概就是在过去,chroot用来做沙盒,但是攻击者可以通过改变路径来达到目的。
而这里的题则是通过ptrace到父进程,将父进程的代码更改,从而达到目的的。
ptrace
ptrace通常用于进程间的attach和信号相互通信。
如gdb、strace等的调试器原理就蕴含在ptrace当中。
gdb
稍微查了点资料了解了一下,gdb主要的执行调试过程,个人理解如下
- gdb ./program的时候,使用fork+execv调用program
- program运行过程中,通过PTRACE_ATTACH和PTRACE_DETACH来追踪和调试
- 在程序下断点的本质就是插入一条中断指令,在遇到中断指令的时候,gdb进程收到program发过来的信号,从而知道断下了,从而可以获取调试的信息。
以上是个人理解,不全面,只是大概的了解了一下。