加深了解system函数
众所周知,在glibc的用户态pwn里面,我们通常会调用system函数来达成我们get shell的目的但是在学习的过程中,我们似乎忽略了对system函数的深入理解,只会单纯的构造调用system来让我们得到get shell的快乐,却没有了解过她的内心。这和渣男有啥区别啊喂!
一、分析system函数
1 | int system(const char * cmdstring) |
由函数我们可以看到,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里面。从而跳脱出此程序的局限,实现了用户与操作系统的交互。
这也是为何使用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的启动参数。