攻防世界Web新手题 easyphp

解题关键:

读懂并逐渐理解php脚本

解题过程:

网站显示php脚本内容如下,首先对代码进行一个简单的分析。

这段代码是一个简单的 PHP 脚本,它接受两个 GET 参数:`a` 和 `b`,以及一个名为 `c` 的 JSON 字符串。让我来解释一下:

1. `highlight_file(__FILE__);`:这会在页面上显示当前 PHP 文件的源代码,所以你可能在浏览器中看到了这个 PHP 文件的代码。

2. 接着是对 `$_GET['a']` 和 `$_GET['b']` 的检查:
   - `$_GET['a']` 必须存在,且是一个大于 6000000 且长度不超过 3 的整数。
   - `$_GET['b']` 也必须存在,并且经过 MD5 加密后的结果的最后 6 位必须是 '8b184b'。

3. 然后是对 `$_GET['c']` 的处理,它被当作 JSON 解码。如果满足以下条件:
   - 是一个数组。
   - 不是一个数字。
   - 数组中包含一个键为 "m" 的值大于 2022。
   - 数组中有一个名为 "n" 的键,其值是一个包含两个元素的数组,第一个元素也是一个数组,且第一个元素中包含字符串 "DGGJ"。

4. 最后如果条件满足,则包含另一个文件 "Hgfks.php",然后输出一个变量 `$flag` 的值。

这段代码看起来像是一个简单的安全性检查,确保传入的参数满足一定的条件才会继续执行,并且最后可能会包含一个文件并输出一个叫做 `$flag` 的变量。

解a:

isset()函数的作用是用来检查一个变量是否已经设置并且非NULL。它接受一个或多个参数,每个参数可以是一个变量、数组元素或者对象属性。如果变量已经设置且不为NULL,则isset()函数返回true,否则返回false

 intval() 函数将尝试将输入值转换为整数。它会尝试截取字符开始的数字(忽略前导空格),直到遇到非数字字符为止,并返回转换后的整数值。如果输入值不能转换为整数,intval() 函数将返回 0(如果不是数字开头)或者最大整数值(如果数值过大)。

$value1 = "12345";
$result1 = intval($value1); // 结果为 12345

$value2 = "42.5";
$result2 = intval($value2); // 结果为 42

$value3 = "abc123";
$result3 = intval($value3); // 结果为 0,因为以非数字开头

$value4 = "123abc";
$result4 = intval($value4); // 结果为 123,因为从数字部分开始到非数字停止

$value5 = "12345678901234567890";
$result5 = intval($value5); // 结果为 PHP 最大整数值,超出整数表示范围

我们可以尝试使用科学计数法使得数字经过intval()后大于6000000的并且长度不超过3

因此a=1e8,或者1e9

解b:

接着分析b,通过python中的hashlib找到经过 MD5 加密后的结果的最后 6 位必须是 '8b184b'的数值,代码如下:

import hashlib
import random

target_suffix = '8b184b'

# 随机生成字符串进行 MD5 加密,直到找到结果的后 6 位匹配目标值
while True:
    random_str = str(random.getrandbits(16))  # 生成随机字符串
    md5_hash = hashlib.md5(random_str.encode()).hexdigest()

    if md5_hash[-6:] == target_suffix:
        print(f"原始字符串:{random_str}")
        print(f"MD5 加密后的结果:{md5_hash}")
        break

运算过后得到b为53724

解c:

依次了解以下c脚本中各个函数的作用

is_numeric() 是 PHP 中的一个内置函数,其作用是判断一个变量是否为数字或数字字符串。具体来说:

  • 如果变量是一个数字(无论是整数、浮点数、正数、负数等),is_numeric() 返回 true
  • 如果变量是一个数值型的字符串(如 "123"、"3.14"),is_numeric() 也会返回 true
  • 如果变量是非数值型的字符串、布尔值、数组、对象、NULL 等,is_numeric() 则返回 false
  1. $c=(array)json_decode(@$_GET['c']);:从 GET 请求参数中取得名为 c 的参数值并尝试将其解析为 JSON 格式,然后将解析后的结果转换为数组。

  2. is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022:如果 $c 是数组,且数组中的键名为 m 的值不是数字、且大于 2022,则进入下一层判断,所以这里我们可以令m前端为比2022大的数最后加上一个字母,比如2088a

  3. if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0])):判断数组中键名为 n 的值是否也是一个数组,并且数组长度为 2,并且第一个元素也是数组,n的格式为一个任意数组加上后续元素,比如[[1,2,3],?]。

  4. $d = array_search("DGGJ", $c["n"]);$d === false ? die("no...") : NULL;在数组 $c["n"] 中查找值为 "DGGJ" 的元素,将结果赋给 $d。如果在 $c["n"] 中找不到 "DGGJ",则输出字符串 "no..." 并终止脚本。

  5. foreach($c["n"] as $key=>$val)$val === "DGGJ" ? die("no......") : NULL;遍历数组 $c["n"] 中的值。如果数组中有值等于 "DGGJ",则输出字符串 "no......" 并终止脚本。与4相矛盾,因此我们必须要绕过其中一个选择array_search()进行绕过,因为当字符与数字进行匹配比较的时候会被转换成数字,因此使字符串的部分为0可以绕过该函数。

 c的组成要使用json编码{"m":"2088a","n":[1,2,3,],0]}

61.147.171.105:63018/?a=1e9&b=53724&c={"m":"2088a","n":[[1,2,3],0]}

 得到flag

总结:

理解php脚本,学会绕过漏洞函数 

  • 35
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值