BuyFlag[极客大挑战 2019]——BUUCTF.19848107是什么?

摘要:开启靶场之后,四处翻找一下,在MENU菜单栏发现关键词flag 可以在这里看到页面给出的提示,money需要100000000(1e8),需要cuit的学生身份,需要正确的密码,就能获得flag 打开f12可以发现源代码有提示, 1.代码逻
开启靶场之后,四处翻找一下,在MENU菜单栏发现关键词flag 可以在这里看到页面给出的提示,money需要100000000(1e8),需要cuit的学生身份,需要正确的密码,就能获得flag 打开f12可以发现源代码有提示, 1.代码逻辑逐行解析 if (isset($_POST['password'])) { // 第一步:检查是否提交了 password 参数 // 如果没有提交,整个 if 块不执行,什么都不发生。 $password = $_POST['password']; // 第二步:将用户提交的 POST 数据赋值给变量 $password if (is_numeric($password)) { // 第三步:检查 $password 是否是“数字”或“数字字符串” // is_numeric() 会返回 true 如果变量是: // - 整数 (如 404) // - 浮点数 (如 404.0) // - 纯数字字符串 (如 "404", "123") // 如果这里是 true,输出错误信息,阻止你通过。 echo "password can't be number</br>"; } elseif ($password == 404) { // 第四步:如果上面不是数字,则检查 $password 是否 等于 404 // 注意:这里使用的是 == (弱比较),而不是 === (强比较) // 如果条件成立,输出成功信息(通常下一步就是给 Flag) echo "Password Right!</br>"; } } 2. 题目的逻辑 目标:不能让 is_numeric($password) 成立(即不能直接输入 404 或 "404")。 如果直接输入 404: is_numeric("404") 为 true -> 触发第一层 if -> 输出 "password can't be number" -> 失败。 但是要让$password==404成立,看似矛盾,因此就需要用到PHP 弱类型比较与类型转换 3. 解题原理:PHP 弱类型比较与类型转换 要解开这个谜题,需要利用 PHP 的两个特性: A. is_numeric() 的严格性 is_numeric() 函数要求字符串必须完全由数字组成(可以包含小数点、负号、科学计数法 e/E)。 is_numeric("404") -> true is_numeric("404a") -> false (因为含有字母 'a') is_numeric("404 ") -> false (某些版本或特定空白符可能不同,但加字母最稳) B. == 弱比较的类型转换 当使用 == 比较一个字符串和一个整数时,PHP 会尝试将字符串强制转换为整数进行比较。 转换规则:PHP 会从字符串开头读取数字,直到遇到第一个非数字字符为止,然后将读取到的部分作为整数值。 例子: "404a" 转换为整数 -> 404 "404abc" 转换为整数 -> 404 "123x456" 转换为整数 -> 123 4. 构造 Payload(攻击载荷) 我们需要一个字符串,它满足以下两个条件: 不是纯数字(绕过 is_numeric)。 转换后等于 404(通过 == 404 检查)。 Payload: password=404a 其次,我们需要money变量为1e8以上,以及需要注意cookie的位置,修改为Cuit's students 5. 提交 由于代码使用的是 $_POST,不能直接在浏览器地址栏输入(那是 GET 请求)。因此使用burp截包发送 总结 这道题的核心知识点是: **is_numeric()**:只认纯数字。 **==**** 弱比较**:会发生类型转换,字符串转整数时只取开头数字部分。 绕过思路:构造一个“以数字开头但包含非数字字符”的字符串(如 404a)。 cookie位置字段值更改身份