使用 protection=validation 解密 .ASPXAUTH Cookie

Posted

技术标签:

【中文标题】使用 protection=validation 解密 .ASPXAUTH Cookie【英文标题】:Decrypting the .ASPXAUTH Cookie WITH protection=validation 【发布时间】:2012-08-23 08:04:25 【问题描述】:

很长一段时间以来,我一直在尝试破译 ASP .ASPXAUTH cookie 并使用 php 对其进行解密。我的理由很大,我需要这样做,别无选择。到目前为止,在 PHP 中,我已经成功地从这个 cookie 中读取了数据,但是在它被加密时我似乎无法做到这一点。不管怎样,就这样吧……

首先您需要更改服务器的 Web.config 文件(需要将保护设置为验证):

    <authentication mode="None">
        <forms name=".ASPXAUTH" protection="Validation" cookieless="UseCookies" timeout="10080" enableCrossAppRedirects="true"/>
    </authentication>

那么在同一个域的PHP脚本中,你可以执行以下操作来读取数据,这是一个非常基本的例子,但就是证明:

$authCookie = $_COOKIE['_ASPXAUTH'];
echo 'ASPXAUTH: '.$authCookie.'<br />'."\n";//This outputs your plaintext hex cookie
$packed = pack("H*",$authCookie);
$packed_exp = explode("\0",$packed);//This will separate your data using NULL
$random_bytes = array_shift($packed_exp);//This will shift off the random bytes
echo print_r($packed_exp,TRUE); //This will return your cookies data without the random bytes

这会破坏 cookie,或者至少是未加密的数据:

现在我知道我可以获取数据,我从我的 Web.config 中删除了 'protection="validation"' 字符串,并尝试使用 PHP mcrypt 对其进行解密。我尝试了无数种方法,但这是一个很有前途的例子(失败了)......

define('ASP_DECRYPT_KEY','0BC95D748C57F6162519C165E0C5DEB69EA1145676F453AB93DA9645B067DFB8');//This is a decryption key found in my Machine.config file (please note this is forged for example)
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_RAND);
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, ASP_DECRYPT_KEY, $authCookie, MCRYPT_MODE_CBC, $iv);//$authCookie is the pack()'d cookie data

然而这失败了。我已经尝试了所有零 @ 16 字节的 IV 变体。我尝试了不同的 Rijndael 尺寸(128 对 256)。我试过 base64_decode()ing,似乎没有任何效果。我找到了这个 *** post here 并开始使用使用 sha256 制作的 key/iv 的变体,但这也不起作用。

有人知道我应该怎么做吗?

【问题讨论】:

你说“我的理由很大,我必须这样做,别无选择。”。你能详细说明一下吗?总有替代方案,SSO 也不例外。深入研究 cookie 加密听起来是个坏主意——如果由于删除了安全漏洞/引入了优化而导致次要框架版本之间的加密发生了变化怎么办?你的解密会突然爆炸。 我并不是说没有技术上的替代方法,我的意思是由于我的原因,我没有可以/想要使用的替代方法。不,框架版本不会有问题。 您是否尝试过相反的方法?是否可以从同一数据中获取未加密数据和加密版本,然后尝试加密未加密数据以匹配加密字符串?也许这样你就可以找到正确的参数。 【参考方案1】:

我知道这对于 OP 来说可能是不可能的,但对于其他沿着这条路线前进的人来说,这是一个简单的选择。

    使用以下方法创建 .net Web 服务:

    公共 FormsAuthenticationTicket DecryptFormsAuthCookie(字符串票证) return FormsAuthentication.Decrypt(ticket);

    将 cookie 从 PHP 传递到 Web 服务:

    $authCookie = $_COOKIE['.ASPXAUTH']; $soapClient = new SoapClient("http://localhost/Service1.svc?wsdl"); $params= 数组( “票” => $authCookie ); $result = $soapClient->DecryptFormsAuthCookie($params);

【讨论】:

IMO 比在 PHP 中解密要好得多。【参考方案2】:

我不知道.NET AuthCookies是怎么加密的,但我可以试着回答一下。

假设加密发生在 AES CBC-IV 模式下,使用随机生成的 IV,您需要先找出 IV 在哪里。

您显示的代码 sn-p 无法工作,因为您正在生成一个随机 IV(这将是不正确的)。话虽这么说,即使你弄错了 IV,在 CBC 模式下,你只会让你解密的密文的前 16 个字节“乱码”,其余的会正确解密 - 你可以用它来测试你是否是正确地完成其余的工作。实际上,在使用随机 IV 时,它很可能会附加到密文中。要检查这是否正确,您可以尝试检查 len(ciphertext) = len(plaintext) + 16。这意味着前 16 个字节很可能是您的 IV(因此应该在尝试之前将其从密文中删除)解密)。

同样在您的代码 sn-p 上,您似乎将密钥用作 ascii 字符串,而它应该是字节数组。试试:

define('ASP_DECRYPT_KEY',hex2bin('0BC95D748C57F6162519C165E0C5DEB69EA1145676F453AB93DA9645B067DFB8'));

此外,这似乎是一个 32 字节的密钥,因此您需要使用 AES-256。不知道authcookie长什么样,但是如果是base64编码的,显然也需要先解码。

希望这会有所帮助!

注意:但是,我不建议对重要的生产代码执行此操作 - 因为如果您尝试实现自己的解密例程,就像您在此处所做的那样,可能会出现很多问题。特别是,我猜想在尝试解密之前必须检查某处应该有一个 MAC 标签,但是在实施你自己的加密时还有许多其他事情可能出错。

【讨论】:

天啊,你我的朋友刚刚度过了我的一周。 你指出了一个我忽略了一个月的缺陷,没有将十六进制打包成二进制!我做到了,并且成功了,通过我的测试脚本中的众多方法之一对其进行了解密。【参考方案3】:

我知道在 PHP 中解密在 .NET 中加密的内容是多么痛苦,反之亦然。

我不得不自己编写 Rijndael 算法(从另一种语言翻译过来)。

这里是算法源代码的链接:http://pastebin.com/EnCJBLSY

源代码末尾有一些使用示例。

但在 .NET 上,您应该在加密时使用零填充。也用ECB模式测试,我不确定CBC是否有效。

祝你好运,希望对你有帮助

编辑:算法在加密时返回十六进制字符串,解密时也需要十六进制字符串。

【讨论】:

以上是关于使用 protection=validation 解密 .ASPXAUTH Cookie的主要内容,如果未能解决你的问题,请参考以下文章

关于Overwrite protection period和Append period问题

为啥没有更多的控制器由于未使用 skip_forgery_protection 而失败?

PhantomJS:使用Cloudflare Protection从网站下载文件

了解崩溃日志 - KERN_PROTECTION_FAILURE

LSA Protection

临时笔记 Protection