基于multiOTP的Windows登录2FA方案

0x01 故事背景

干了N年的IT支持,电脑故障处理起来得心应手,“独孤求败”啊,经常吹嘘小伙伴:一般性的电脑故障,难不倒俺。

突然有一天,被打脸了。怎么回事?是这样的:一天下午同事电话我,他在外地出差,昨天电脑还好好的,今天就不能登陆了。接到报障后,盘问一番,发现电脑掉域了,微微一笑,这不小菜一碟吗?让他拿过来重新加个域就行啦,正准备开口,大脑突然一愣,等等,感觉那里不太对劲。尼玛,在外地?在外地?在外地?此刻浮现头脑里的方案有两种:要么交出管理员密码,要么电脑带回公司处理(可别指望PE啥的)。根据公司目前情况两种方案都不可行啊。为了规避下次再被打脸,开始琢磨这个问题,在外人员把电脑带回来肯定行不通,那我们有没有办法可以将管理员密码交出去,却又能保证系统安全呢?答案是肯定的。

0x02 系统简述

基于multiOTP的Windows安全登录正好解决所需。

  • multiOTP简介
multiOTP 是一个强大的双因素身份验证的GNU LGPL实现PHP类,针对HOTP / TOTP的OATH认证,继承了google的OTP方案, 可以通过pam模块与Radius验证服务器集成,安装包已经包括了Radius和Google OTP 模块。
  • OTP(动态口令)
动态口令具有极高的安全性,动态生成,30秒改变一次,而且不能重复使用,同时还和普通口令一样的简单易用。
  • OTP算法的Windows系统安全登录步骤
  • 启动Windows,检查是否安装有OTP登录拦截插件,如果是,则展示带有动态口令输入框的定制登录界面
  • 打开手机动态口令APP,并查看当前动态口令,在电脑登录界面输入用户名、密码,以及动态口令,并点击登录按钮,登录拦截插件对该用户名、密码进行校验,校验是否成功,如果是,登录拦截插件利用OTP算法校验动态口令,进一步校验是否成功,如果是,则成功进入Windows系统桌面。

0x03 系统部署

如果觉得上面的内容乏味了,来,我们正式撸起袖子干它

  • 系统对象:

目前微软发布的所有WIN10系统

  • 系统目标:

  • 实现加域电脑的本地管理员账号登录的2FA(2 Factor Authentication,双因子验证)
  • 只允许本人的域账号登陆主机,其他域账号不允许登陆(安全考虑)
PS:这里多啰嗦两句:multiOTP 既支持实现客户端/服务器功能,也能够支持本地唯一强大的认证,由于我只对本地账号二次验证,域账号不做要求,因此,选择了后者,小伙伴们可以根据实际情况选择。

详细介绍可以参考:https://github.com/multiOTP/multiotp/wiki
  • 系统条件:

  • 系统部署:

  • 安装multiOTP Credential Provider客户端

开始安装之旅吧!

首先我们见到如下的界面,这点英文相信还难不倒小伙伴们,第一个框,我就写个TC吧,你们随意,第二个和第三个框,注意了,还记得我上面多啰嗦的两句吗?如果你们是部署的客户端/服务器功能,那么这里的第二个框就需要填写以下服务器的URL了,第三个框就是客户端与服务器的共享密码了。填好了就NEXT吧!

下面这个界面,我就说一点,默认第一个选项勾选(实现远程访问客户机时使用OTP认证),我这里不需要,所有勾选就去掉了。(其他几个选项,直译就明白啥意思了)

继续next,下面这个界面设置很关键,也是“最麻烦”的设置,我们需要了解下:

第一个框是要输入windows系统账号(即为下面生成的OTP账号);

第二个框是要输入windows系统账号密码;

第三个框是要输入windows系统账号对应的OTP的密码;
第一个“坑”出现了
如果此时我们输入账号密码后(不管正确还是不正确),贸然点击“Test the multiOTP…..”这个长长的按钮,下方的“Credential Provider state”会显示NOT activated,此时如果点击next 下一步的话,虽然软件安装完了,但是OTP功能模块却没有激活,windows登陆界面没有任何变化,后面再去建OTP验证账号也是无济于事的。所以在点击 “Test the multiOTP…..”这个测试按钮前,我们需要先进行下面的操作:
打开命令提示符,跳转到multiOTP的目录下,执行以下命令,即可新建OTP账号,并生成对应账号的二维码,例如:
1)multiotp -fastcreatenopin administrator 建立OTP账号

 第二个“坑”
此账号必须是系统中存在的账号,不能是自己随便定义的,否则无效
2)multiotp -qrcode administrator administrator.png 建立OTP账号对应二维码.新建完成后,在手机上安装Google Authenticator,使用Google Authenticator扫描刚才生成的二维码(二维码的默认路径在软件安装目录下),填写好OTP账号、密码,将扫描得到的6数字,填入“OTP for user”,此时就可以 点击“Test the multiOTP…..”这个长长的按钮,下方的“Credential Provider state”会显示installed and activated,此时如果点击next 下一步的话,至此,multiOTP Credential Provider安装完成。
  • 配置multiOTP以同步Active Directory中的用户

接下来,我们要用到很多multiOTP 的命令行

第三个“坑”来了
 一般程序命令行参数查看都是什么“/?”或者“?”,multiotp的查看命令行参考的命令为“multiotp -help”,另外,multiotp的命令行参数赋值虽然官方文档给出了很多,但部分赋值信息却无法得知,比如:我们要关闭所有AD用户的2FA认证(程序默认AD用户是开着的),命令应该这样写的:multiotp -config ldap_default_algorithm=without2fa,坑了好久才弄出来的,心累啊
进入正题,继续干活,配置multiOTP以同步Active Directory中的用户:
打开命令提示符,输入以下命令完成配置并同步AD用户,例如:
至此,AD用户同步完成。

通过以上两步,就可以实现加域电脑本地账号登录的2FA。

各位看官看看上面的两幅登陆界面,基本功能已实现,差不多解决了用户的痛点,感觉我们已经大功告成,细心的小伙伴一定会发现,我们还有很多坑需要填一填。

最大的“坑”来了

问题一:本地账号和AD账号登陆界面都会出现OTP选项,这会给用户带来困扰;

问题二:本地账号和AD账号登陆界面domian都显示的企业域名,误以为登陆的都是域账号;

问题三:界面含有“multiOTP Login” 等英文字样

显然目前的界面虽然能用却很不友好,部署到生产环境,就要有点追求了,撸起袖子继续干吧。

 

  • 系统优化:

还记得上面提到的multiOTPCredentialProvider程序包吗?对了,这个就是修改界面的源码(C++编写的),里面有一对文件,找到 multiOTPCredentialProvider.sln 这个文件我们用vs2015打开它,内容如下:
我们只需对红色选中的两个文件稍加修改即可,在common.h文件中,将原先的英文修改成我们熟悉的中文字(根据需要自行修改),修改如下:
在MultiotpCredential.cpp文件中,我们先修改第135行的代码如下:
修改第233行的代码如下:

我们还可以修改登陆界面的图片,代码在502行的类中,细节的修改还有很多,不再举例。

然后我们需要在源码的尾部添加一个 LPWSTR转char* 的方法,代码如下:
接下来在257行插入一段关键代码,判断本地账号显示OTP输入框,域账号不显示,代码如下:
将659行下面这段代码
修改如下,用于解决动态显示登陆账号关联的域名
OK,修改完毕,我们将编译好的DLL文件“MultiotpCredentialProvider.dll”复制到C:\windows\System32下,我们来看下撸得剁手后的效果吧!

对比之前的两个界面,该填的坑已经填好了,大功告成!

 

  • 系统完善:

基于multiOTP登陆的Windows系统基本完工了,下一个问题来了:如何能在生产环境中保证每台电脑都只允许是自己的域账号登陆呢?每台电脑的OTP账号的二维码如何收集?为了解决这个问题,我们是这么做的:
  • 首先将安装好multiOTP程序的系统部署到MDT中(MDT部署这里就不罗嗦了)
  • 写个脚本,放入MDT的application中,脚本功能如下:
    
  • 后台接受OTP二维码,并将二维码在WEB前台可查询,以便IT解决用户故障
将本地administrator账号对应OTP二维码发送后台的代码如下:
如果OTP账号建立失败,那么IT手机微信端也会收到,如下报错:
WEB查询页面可通过用户的域账号查询本机的OTP二维码,页面如下:

0x04 结束语

multiOTP安装非常简单,multiOTP内部的功能还是很强大的,感兴趣的伙伴可以查阅官网资料详细研究一番,另外要想玩转系统,我们必须要结合公司的具体场景,制定完整流程,形成一套完善系统,便于故障的处理以及后续的问题分析。

小提示: 因为采用的是TOTP算法,那么客户端的时间需要与网络时间同步,否则将会导致验证失败。如果由于时间不一致或其他未知原因导致验证失败,那么可以使用关闭2FA功能的账号登录电脑后卸载multiOTP Credential Provider即可关闭所有账号的2FA功能。

欢迎有兴趣的小伙伴留言一起讨论。欢迎加入我们的星球一起发展