在CTF中常用到的PHP函数

 CTF / Web
被浏览

本文列举了一些在 CTF 比赛中常用到的 PHP 函数。

参数与字符串相关的函数

在 PHP8.x 中,这些函数不再接受数组的参数,会抛出 Fatal error 并结束运行,以下不再赘述。

在之前版本中能接受数组型参数这一特性常被网上称之为内置函数的松散性,虽然我也不懂为啥这样叫。。

md5

以 32 字符十六进制数字形式返回散列值。

1
md5($str[, bool $raw_output = FALSE])
  • raw_output
    如果可选的 raw_output 被设置为 TRUE, 那么将以 16 字节长度的原始二进制格式返回

如果参数为数组将会返回 NULL 并发出 Warning。

也可以借助返回以 0e 开头的数字字符串来实现绕过弱类型比较。

一些常见的例子:

字符串md5值
byGcY0e591948146966052067035298880982
sonZ7y0e463306343746311593316642162425
QNKCDZO0e830400451993494058024219903391
2406107080e462097431906509019562988736854
s878926199a0e545993274517709034328855841020
s155964671a0e342768416822451524974117254469
s214587387a0e848240448830537924465865611904
s1665632922a0e731198061491163073197128363787
s1836677006a0e481036490867661113260034900752

当然真正意义上的 md5 碰撞也是存在的,不过 CTF 应该不会涉及这么深吧。。

贴个链接:https://natmchugh.blogspot.com/2014/10/how-i-created-two-images-with-same-md5.html

有意思的是,如果第二个参数是 true,可以弄出神奇的效果。

假如有这样的 SQL 语句:

1
$sql = "SELECT * FROM admin WHERE username = 'admin' and password = '".md5($password, true)."'"

然后有这样的字符串:

1
2
3
4
echo md5("129581926211651571912466741651878684928", true);
// T0Do#'or'8
echo md5("ffifdyop", true);
// 'or'6]!r,b

就能绕过 md5 的加密了。

sha1

和 md5 函数利用差不多,真正意义上的 sha1 碰撞也是存在的,不过 CTF 应该不会涉及这么深吧。。

贴个链接:https://shattered.it/

hash

1
2
3
4
5
6
hash(
string $algo,
string $data,
bool $binary = false,
array $options = []
): string

其实是一个哈希函数的集中调用,具体有哪些算法可见 hash_algos() 返回的数组,而常用的 md5、sha1 等也包括在里面,只是因为更常用被单独列出来了。

在 PHP8.x 之后传入不存在的哈希算法会直接抛出错误,之前则是返回一个 false,而且这个信息在官方中文文档没有提及,只有英文原版才有 Changelog

一些和 md5 一样神奇的骚操作:

1
2
3
echo hash("whirlpool", '364383',  true);
// TNF /$=/!%.i<0'='IT Q
// r=%͞nNŶvL

strcmp

1
strcmp($str1, $str2); // 比较两个字符串是否相等

返回值:

  • 如果 str1 小于 str2 返回 < 0

  • 如果 str1 大于 str2 返回 > 0

  • 如果两者相等,返回 0

如果某个参数为数组将返回 NULL 并发出 Warning。

存在弱类型比较的函数

in_array

1
in_array(mixed $needle, array $haystack, bool $strict = false): bool

参数名非常的生动形象,大海捞针(●’◡’●)。

注意到第三个参数 strict,默认是 false,即采用弱类型比较(==)来查找,可以参考我的另一篇文章,里面有对 PHP 弱类型比较的详解。。

举个例子:

1
2
3
<?php
var_dump(in_array('1e05', [100000, 2, 3, 4, 5])); // bool(true)
var_dump(in_array('1e05', [100000, 2, 3, 4, 5], true)); // bool(false)
1
array_search(mixed $needle, array $haystack, bool $strict = false): int|string|false

和 in_array 类似。

举个例子:

1
2
3
<?php
var_dump(array_search('5e05', [1, 2, 3, 4, 500000])); // int(4)
var_dump(array_search('5e05', [1, 2, 3, 4, 500000], true)); // bool(false)