用PHP破解Bcrypt?可以轻松包含任何恶意负载

Rom*_*man -4 php security encryption bcrypt collision

盐:可以是任何东西.
工作因素:可以是任何东西.
以下所有内容都生成相同的哈希!

$pad = base64_decode('/gB=');
$data = array(
    'LegitimatePayload',
    'LaterSwitchedToMaliciousPayload',
    'Abracadabra',
    'hatIsGoingOn',
    'CanBeAlmostAnything',
);

foreach($data as $str){
    echo crypt($pad.$str, '$2a$04$AnySaltHere')."<br>\n";
}
Run Code Online (Sandbox Code Playgroud)


输出:

$2a$04$AnySaltHere$$$$$$$$$$.m/QKi19jyBmSuP2VMcVuFRw.weCNRBa
$2a$04$AnySaltHere$$$$$$$$$$.m/QKi19jyBmSuP2VMcVuFRw.weCNRBa
$2a$04$AnySaltHere$$$$$$$$$$.m/QKi19jyBmSuP2VMcVuFRw.weCNRBa
$2a$04$AnySaltHere$$$$$$$$$$.m/QKi19jyBmSuP2VMcVuFRw.weCNRBa
$2a$04$AnySaltHere$$$$$$$$$$.m/QKi19jyBmSuP2VMcVuFRw.weCNRBa
$2a$04$AnySaltHere$$$$$$$$$$.m/QKi19jyBmSuP2VMcVuFRw.weCNRBa
Run Code Online (Sandbox Code Playgroud)

编辑:
这是一个字符串,它具有相同的前两个字节但具有不同的散列:
base64_decode('/ gBQyoK71jVY/J7QuBNJuFdxyf2eTBCs42chkx6ZvpJYszpzg ===')
如果php在第一个NUL字节处停止,那么你如何解释这个?

Joa*_*son 10

你的所有字符串都有一个前缀 - 当运行时base64_decode- 产生一个0xfe字符和一个0x00带有额外变化的字符 - 字符在0x00之后.由于标准crypt将停留在一个0x00字符上,因此所有的crypt调用只会加密该0xfe字符.

您可以通过调用来验证它

echo crypt("\376", '$2a$04$AnySaltHere')."<br>\n";
Run Code Online (Sandbox Code Playgroud)

这将得到相同的结果.

我假设你base64_decode错误地使用意味着实际打电话base64_encode.

编辑:罗马指出,字符串

"/gBQyoK71jVY/J7QuBNJuFdxyf2eTBCs42chkx6ZvpJYszpzg==="
Run Code Online (Sandbox Code Playgroud)

实际上 - 尽管有相同的前缀 - 完全隐藏其他东西.这是因为该字符串实际上是无效的base64和base64_decode返回false.这导致字符串加密到与空字符串相同的散列.

  • 使用`for($ i = 0; $ i <strlen($ pad); $ i ++)printf("0x%02x \n",ord($ pad [$ i]));`查看实际字节数. (2认同)

wim*_*vds 5

您没有提供任何有效的base64编码字符串,因此base64_decode可能只会为所有测试用例返回false,因此它会对它们进行相同的加密.为什么你还在使用base64_decode?

  • 你没有明白这一点:你提供的字符串不是*base64编码的,因此base64_decode将*always*返回false.没有漏洞,只是你的代码没有任何意义. (2认同)