首先先进入题目,题目是这样的
这是一个留言板界面没有什么信息,只有发帖可以点击,我们先点击发帖查看一下
随便输入一下看看提交上去有什么
此时需要我们登录,在这里给我们提示了用户名和密码,但是用户名后隐藏了后三位,所以我们可以考虑用爆破的方法爆破后三位
爆破后发现发现666与其他数值不同,确认密码后三位为66,登录进去就可以去发帖了
接下来用dirsearch扫描,发现存在.git文件那应该存在.git文件泄露,用GitHack下载发现有一个write_do.php,但是代码有缺失查一下之前提交的版本,单独用git log不能全部显示,直接用git log --all
可以看到,head指针指向的是最早一次commit,通过git reset --hard e5b2a2443c2b6d395d06960123142bc91123148c
命令将head指向第一个commit,得到完整的write_do.php
<?php
include "mysql.php";
session_start();
if($_SESSION['login'] != 'yes'){
header("Location: ./login.php");
die();
}
if(isset($_GET['do'])){
switch ($_GET['do'])
{
case 'write':
$category = addslashes($_POST['category']);
$title = addslashes($_POST['title']);
$content = addslashes($_POST['content']);
$sql = "insert into board
set category = '$category',
title = '$title',
content = '$content'";
$result = mysql_query($sql);
header("Location: ./index.php");
break;
case 'comment':
$bo_id = addslashes($_POST['bo_id']);
$sql = "select category from board where id='$bo_id'";
$result = mysql_query($sql);
$num = mysql_num_rows($result);
if($num>0){
$category = mysql_fetch_array($result)['category'];
$content = addslashes($_POST['content']);
$sql = "insert into comment
set category = '$category',
content = '$content',
bo_id = '$bo_id'";
$result = mysql_query($sql);
}
header("Location: ./comment.php?id=$bo_id");
break;
default:
header("Location: ./index.php");
}
}
else{
header("Location: ./index.php");
}
?>
这里的write和comment分别对应发帖和留言界面 可以看到所有参数都进行了addslashes函数处理但是在cmment中,对于category的值从数据库取出来没有进行转义,直接拼接到sql insert语句中,这就存在二次注入的可能。
所以我们先发帖
.在提交留言处输入*/#
(这个sql语句是换行的,所以我们无法用单行注释符,必须用/**/拼接)
在sql语句 拼接 并 闭合 的情况如下
insert into comment
set category = ' ',content=user(),/*',
content = '*/#',
bo_id = '$bo_id'";
利用content的回显即可看到结果:数据库名为ctf
读取user
读取/etc/passwd
发现存在www用户,读取用户的命令执行历史
先进入/tmp目录,解压缩了html.zip文件(得到/tmp/html),之后将html.zip删除了,拷贝了一份html给了/var/www目录(得到/var/www/html),之后将/var/www/html下的.DS_Store文件删除,但是/tmp/html下的.DS_Store文件没有删除,查看一下,然后因为这种文件直接读取通常存在乱码,所以要转进制读取才行。
这是一个假的flag,真的flag可能在/var/www/html目录下
解码