A2ur2的梦想小屋

我许下的愿望该向谁去说明

0%

about system

加深了解system函数

众所周知,在glibc的用户态pwn里面,我们通常会调用system函数来达成我们get shell的目的但是在学习的过程中,我们似乎忽略了对system函数的深入理解,只会单纯的构造调用system来让我们得到get shell的快乐,却没有了解过她的内心。这和渣男有啥区别啊喂!

一、分析system函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
int system(const char * cmdstring)
{
pid_t pid;
int status;

if(cmdstring == NULL){

return (1);
}


if((pid = fork())<0){

status = -1;
}
else if(pid == 0){
execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
-exit(127); //子进程正常执行则不会执行此语句
}
else{
while(waitpid(pid, &status, 0) < 0){
if(errno != EINTER){
status = -1;
break;
}
}
}
return status;
}

由函数我们可以看到,system函数主要是对execl函数进行了封装,其中execl就是我们启动shell的关键函数。

system参数:字符类型的指针,即传入字符串

fork函数:复制一个子进程用于继承父进程的环境并且起shell

其中fork如果成功复制出了子进程,就会执行

execl(“/bin/sh”, “sh”, “-c”, cmdstring, (char *)0);这一行

浅浅解析一下execl函数:

/bin/sh:是execl函数要求传入的文件存储绝对路径

“sh”, “-c”:执行命令的前缀,相当于./

cmdstring:要运行的二进制文件,也就是执行的命令

这个命令中也可以附加命令的参数,例如ls -l,或者cat flag

二、我们如何理解system(“/bin/sh”)能拿到shell

其中”/bin/sh”是起到一个软连接的作用

/bin目录下是系统的一些指令。bin为binary的简写主要放置一些系统的必备执行档例如:cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar等。

sh则是bin目录下的一个文件,可以理解成一个启动shell的命令

所以system(“/bin/sh”)这一个我们通常在glibc pwn中用于get shell的函数,实际上是调用了execl,fork了一个子进程并且在子进程中启动了位于/bin/sh下的sh命令。相当于我们程序和ubuntu默认的shell建立起了连接,在调用的system(“/bin/sh”)程序中用file /bin/sh可以查看到我们link到了dash里面。从而跳脱出此程序的局限,实现了用户与操作系统的交互。

xeomKe.png

这也是为何使用system(“cat flag”)也可以,本质上就是在子进程中启动了位于/bin/sh下的cat命令,并且以flag这个作为参数。

三、在ctf中一些关于system的小trick

众所周知,在get shell的过程中,我们可以构造system(“sh”)来达到和/bin/sh同样的效果,这是为什么可以参考上面的例子。

与此同时,system(“$0”)也能够拿到shell,这是因为linux中 $0就是该bash文件名,个位数的。所以system(“$0”)和system(“/bin/sh”)效果相同

另外,在启动sh的时候可以加入一些命令,例如重定向。个人理解就是将其作为启动sh的启动参数。