You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP技术问询:如何让pack()返回与普通字符串等效的字符串?

嘿,你的问题根源是对pack('V')的误解!

你以为pack('V', 0x41)会生成单个"A"字符?其实不是——V格式代表32位无符号长整型(小端序),所以0x41(十进制65)打包后得到的是4字节序列:\x41\x00\x00\x00,也就是一个"A"后面跟着三个空字节。这就是所有困惑的起点。

为什么看起来和"A"一模一样?

  • echo的“偷懒”输出:PHP的echo碰到字符串里的空字节\x00就会停止输出,所以你只能看到开头的"A",但实际字符串长度是4,而普通的"A"长度只有1。随手跑个strlen(pack('V', 0x41))和strlen("A")就能验证,结果会是4和1,差异明显。
  • mb_detect_encoding的局限性:这个函数只检查字节是否在目标编码的范围内,ASCII覆盖0-127,\x41和\x00都符合,所以它会告诉你两者都是ASCII,但这完全不代表内容相同。

SQL查询为啥执行失败?

当你把这个4字节字符串拼进SQL语句后,实际生成的查询是:

SELECT item_name, item_description FROM items WHERE item_name LIKE 'A\x00\x00\x00%'

你的item_name字段里都是正常的无空字节的字符串,自然匹配不到任何记录,看起来就像查询“失败”了。而且有些数据库驱动在处理带空字节的字符串时,还可能出现解析异常,进一步导致查询出错。

结合你的CTF注入场景

这个空字节特性可是SQL注入里的经典玩法——空字节截断。比如如果你的代码有前缀过滤,攻击者可以用pack('V', ...)生成带空字节的payload,让数据库在处理时“忽略”空字节后的内容,或者绕过某些基于字符串长度的检查。举个例子,攻击者构造$querystr = pack('V', 0x41) . "' UNION SELECT flag, '' FROM flags -- ",空字节可以用来绕过部分WAF规则,或者在特定场景下截断SQL语句,从而触发注入漏洞。

最后给你个直观验证方法:用bin2hex()看两者的真实内容——bin2hex(pack('V',0x41))会输出41000000,而bin2hex("A")是41,一眼就能看出差异。

内容的提问来源于stack exchange,提问作者neatzsche

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:34:35