我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

表面上来看,这个ntlmv2的验证过程,和realm等登陆方式,是没有什么区别的。通常的理解下,可能区别的仅仅是算法。然而,事实却并非如此。因为ntlm这种方式,会默认发送当前系统的用户名、加密后的密码以及域等敏感信息到服务器...

苏南大叔:Net-NTLMv2授权逻辑过程简要描述,敏感登陆信息泄漏 - Net-NTLMv2授权逻辑过程简要描述,敏感登陆信息泄漏
Net-NTLMv2授权逻辑过程简要描述,敏感登陆信息泄漏(图2-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔的编程经验文章。本文测试环境:win10nginx@1.15.11php@8.2.9ntschrome@121.0.6167.140internet explorer

写在前面

这种NTLM的鉴权方式,是基于401状态的。所以,你可以复习一下401状态码的几篇文章:

另外,本文是对于Net-NTLMv2原理的一个不详细解读,是基于ntlm.php中这个类库的另类解读。ntlm.php的出处,可以参考文章:

第一步,发出NTLM

第一步,就是非常好理解的,发出401状态码和NTLM的鉴权方式附加信息。

$headers = getallheaders();
if (!isset($headers['Authorization'])){
  header('HTTP/1.1 401 Unauthorized');
  header('WWW-Authenticate: NTLM');
  exit;
}

然而,在本文中,在chrome浏览器里面执行的时候,这里本该弹出的登陆对话框却没有弹出,直接走下一步。在隐私模式下,弹出了对话框,并且后续逻辑也并没有得到开机密码。调试结果表面:在测试环境里面,谷歌浏览器收到NTLM的对话请求后,直接发送了加密信息过去,并没有按照约定弹出对话框,瞬间完成了两次交互。【看出来谁是间谍了么?】

第二步,\x01

这一步是服务器端发出特定的加密信息。

$auth = $headers['Authorization'];
if (substr($auth,0,5) == 'NTLM ') {
  $msg = base64_decode(substr($auth, 5));
  if (substr($msg, 0, 8) != "NTLMSSP\x00")
    die('error header not recognised');
  if ($msg[8] == "\x01") {
    $msg2 = "NTLMSSP\x00\x02\x00\x00\x00".
      "\x00\x00\x00\x00". // target name len/alloc
      "\x00\x00\x00\x00". // target name offset
      "\x01\x02\x81\x00". // flags
      "\x00\x00\x00\x00\x00\x00\x00\x00". // challenge
      "\x00\x00\x00\x00\x00\x00\x00\x00". // context
      "\x00\x00\x00\x00\x00\x00\x00\x00"; // target info len/alloc/offset
    header('HTTP/1.1 401 Unauthorized');
    header('WWW-Authenticate: NTLM '.trim(base64_encode($msg2)));
    exit;
  }
}

苏南大叔:Net-NTLMv2授权逻辑过程简要描述,敏感登陆信息泄漏 - poc截图
Net-NTLMv2授权逻辑过程简要描述,敏感登陆信息泄漏(图2-2)

值得注意的是:
对比ntlm.php中的相关代码,就可以发现:challenge是固定值\x00\x00\x00\x00\x00\x00\x00\x00。这里是个特殊的构造值。

第三步,\x03

这一步就是泄漏敏感信息的关键点了,代码隐藏。

newsn.net:这里是【作者】可见内容

这里获得了一个非常长的hash字符串,并且每次的结果都不一样。类似如下:

sunan::SUNAN-AIR:0000000000000000:cxxxxxxxxxxxxxxxxxxxbc:01010000000000000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0068000000000000000000

从这个里面,理论上就可以解读出苏南大叔的开机密码。所以,这里比如是不完整数据了,您也不用尝试了。对hash字符串的解读,需要使用特殊工具进行hash多次尝试验证。这个问题就留待后续文章进行解读了。

相关文章

这里就放几篇ctf夺旗赛的链接吧..

总结

401状态码太邪恶了,看来electron默认不支持401状态,是个非常明智的选择。

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   php    ctf