table {
border-collapse: collapse;
width: 100%;
margin-bottom: 1rem;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
tr:nth-child(even) {
background-color: #f9f9f9;
}
pre {
background-color: #f8f8f8;
padding: 15px;
border-radius: 4px;
overflow-x: auto;
}
1、目前,HoneyResolver.py 很容易区分真实和虚假结果,因为所有虚假结果都解析到同一个 IP 地址。修改代码,仅将某些虚假子域名解析为为每个子域名分配的唯一 IP 地址。
可以对 HoneyResolver.py 进行如下修改:
1. 定义一个字典来存储特定虚假子域名及其对应的唯一 IP 地址。
2. 在 `resolve` 函数中,检查请求的子域名是否在该字典中,如果是,则使用对应的唯一 IP 地址进行响应;如果不是,则使用原来的蜜罐 IP 地址。
以下是修改后的代码示例:
```python
from dnslib import *
from dnslib.server import DNSServer
host = "localhost"
port = 8053
subdomains = {
"www.": "10.0.0.1",
"smtp.": "10.0.0.2"
}
domain = "example.com"
honeyip = "10.0.0.0"
# 新增:特定虚假子域名及其唯一 IP 地址的字典
fake_subdomains = {
"fake1.": "10.0.0.3",
"fake2.": "10.0.0.4"
}
blocked = {}
class HoneyResolver:
def resolve(self, request, handler):
subdomain = str(request.q.qname.stripSuffix(domain + "."))
if subdomain in subdomains:
reply = request.reply()
ip = subdomains[subdomain]
reply.add_answer(RR(
rname=request.q.qname,
rtype=QTYPE.A,
rclass=1,
ttl=300,
rdata=A(ip)
))
elif subdomain in fake_subdomains:
# 新增:如果是特定虚假子域名,使用唯一 IP 地址
reply = request.reply()
ip = fake_subdomains[subdomain]
reply.add_answer(RR(
rname=request.q.qname,
rtype=QTYPE.A,
rclass=1,
ttl=300,
rdata=A(ip)
))
else:
reply = request.reply()
reply.add_answer(RR(
rname=request.q.qname,
rtype=QTYPE.A,
rclass=1,
ttl=300,
rdata=A(honeyip)
))
return reply
resolver = HoneyResolver()
server = DNSServer(resolver, port=port, address=host)
server.start_thread()
import time
while True:
time.sleep(5)
server.stop()
上述代码通过新增
fake_subdomains
字典来存储特定虚假子域名及其唯一 IP 地址,并在
resolve
函数中添加了对这些子域名的检查和处理。
##2、AutorunDetection 使用 psutil 库确定进程的 PID。修改代码以提供有关可疑进程的更多信息,例如它们的创建时间或父 PID。
要修改 `AutorunDetection.py` 代码以提供有关可疑进程的更多信息,如创建时间和父 PID,可以在 `DetectAutorunProcess` 函数中添加相应的代码。以下是修改后的代码:
```python
import win32con
from win32api import GetLogicalDriveStrings
from win32file import GetDriveType
import os.path
import psutil
def GetRemovableDrives():
driveStrings = GetLogicalDriveStrings()
drives = [item for item in driveStrings.split("x00") if item]
return [drive for drive in drives if GetDriveType(drive) is win32con.DRIVE_REMOVABLE]
def CheckAutorun(drive):
filename = drive + "Autorun.inf"
if os.path.isfile(filename):
print("Autorun file at %s" % filename)
with open(filename, "r") as f:
for line in f:
if line.startswith("Open"):
ind = line.index("=")
return line[ind + 1:].rstrip()
else:
return None
def DetectAutorunProcess(executable):
for proc in psutil.process_iter():
if executable == proc.name():
try:
create_time = proc.create_time()
parent_pid = proc.ppid()
print("Autorun file running with PID %d, created at %s, parent PID: %d" % (proc.pid, create_time, parent_pid))
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
pass
for drive in GetRemovableDrives():
executable = CheckAutorun(drive)
if executable:
DetectAutorunProcess(executable)
在这个修改后的代码中,
DetectAutorunProcess
函数在找到匹配的进程时,会尝试获取该进程的创建时间和父 PID,并将这些信息打印出来。如果在获取这些信息时出现异常(例如进程已不存在、没有访问权限或进程是僵尸进程),则会捕获异常并继续处理下一个进程。
3、已知WMIDetection可使用Windows事件日志来识别使用WMI启动的进程的PID,编写Python代码,利用这个PID,使用psutil和其他Python库来收集有关该进程和可执行文件的更多信息。
以下是一个示例代码,展示了如何结合
WMIDetection
获取的 PID,使用
psutil
库来收集有关进程和可执行文件的更多信息:
import psutil
import subprocess
import wmi
# 假设WMIDetection.py中的代码获取PID的部分已经完成,这里简单模拟获取PID
# 这里调用WMIDetection.py获取PID,实际中可能需要根据WMIDetection.py的具体实现来获取PID
# 这里只是示例,假设WMIDetection.py会输出类似 'Process notepad.exe launched with PID 1234' 的信息
output = subprocess.check_output(['python', 'WMIDetection.py']).decode('utf-8')
lines = output.split('
')
for line in lines:
if 'Process' in line and 'launched with PID' in line:
parts = line.split(' ')
pid = int(parts[-1])
try:
process = psutil.Process(pid)
# 收集进程的更多信息
print(f'进程名称: {process.name()}')
print(f'进程可执行文件路径: {process.exe()}')
print(f'进程命令行参数: {process.cmdline()}')
print(f'进程创建时间: {process.create_time()}')
print(f'进程CPU使用率: {process.cpu_percent(interval=1)}%')
print(f'进程内存使用率: {process.memory_percent()}%')
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
print(f'无法获取进程 {pid} 的信息')
这段代码首先模拟调用
WMIDetection.py
来获取 PID,然后使用
psutil.Process()
方法根据 PID 创建一个进程对象,最后通过该对象的属性和方法收集有关进程和可执行文件的更多信息。
4、修改DetectAntivirusService.py,通过将检测到的服务的Start值设置为0x04来禁用该服务。
要实现此修改,需在
DetectAntivirusService.py
中添加以写权限打开键并设置
Start
值为
0x04
的代码。以下是修改后的示例代码:
import winreg
reghive = winreg.HKEY_LOCAL_MACHINE
regpath = r"SYSTEMCurrentControlSetServices"
av_list = ['MBAM'] # 可扩展此列表包含其他AV关键字
try:
key = winreg.OpenKey(reghive, regpath, 0, access=winreg.KEY_READ)
numKeys = winreg.QueryInfoKey(key)[0]
for i in range(numKeys):
subkey = winreg.EnumKey(key, i)
for name in av_list:
if name in subkey:
subPath = r"%s\%s" % (regpath, subkey)
# 以写权限打开子键
k = winreg.OpenKey(reghive, subPath, 0, winreg.KEY_ALL_ACCESS)
numVals = winreg.QueryInfoKey(k)[1]
for j in range(numVals):
val = winreg.EnumValue(k, j)
if val[0] == "Start" and val[1] == 2:
print("Service %s set to run automatically" % subkey)
# 设置Start值为0x04以禁用服务
winreg.SetValueEx(k, "Start", 0, winreg.REG_DWORD, 0x04)
print("Service %s has been disabled" % subkey)
winreg.CloseKey(k)
winreg.CloseKey(key)
except Exception as e:
print(e)
注意,运行此代码需要管理员权限。
5、特殊登录事件的Windows事件日志包含与目标账户关联的权限。修改DetectAdminLogin.py以收集此信息。
修改 DetectAdminLogin.py 收集特殊登录事件中的权限信息
要修改
DetectAdminLogin.py
以收集特殊登录事件中目标账户的权限信息,可按照以下步骤操作:
在
DetectAdministratorLogin
函数中,获取事件中的权限信息。
在输出登录尝试信息时,将权限信息一并输出。
以下是修改后的代码:
import win32evtlog
server = "localhost"
logtype = "Security"
flags = win32evtlog.EVENTLOG_FORWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ
def QueryEventLog(eventID, filename=None):
logs = []
if not filename:
h = win32evtlog.OpenEventLog(server, logtype)
else:
h = win32evtlog.OpenBackupEventLog(server, filename)
while True:
events = win32evtlog.ReadEventLog(h, flags, 0)
if events:
for event in events:
if event.EventID == eventID:
logs.append(event)
else:
break
return logs
def DetectAdministratorLogin():
events = QueryEventLog(4672)
for event in events:
if event.StringInserts[0].startswith("S-1-5-21"):
# 获取权限信息,假设权限信息在StringInserts的某个位置,这里假设是索引2
privileges = event.StringInserts[2] if len(event.StringInserts) > 2 else "Unknown"
print("Login attempt by %s at %s with privileges: %s" % (event.StringInserts[1], event.TimeGenerated, privileges))
DetectAdministratorLogin()
说明:
上述代码中,假设权限信息位于
event.StringInserts
的索引
2
位置。
如果该位置无数据,则权限信息显示为
"Unknown"
。
在输出登录尝试信息时,会包含权限信息。