墨菲定律指明"Anything that can go wrong will go wrong.",即如果事情有变坏的可能,不管这种可能性有多小,它总会发生。
在网络安全领域也是同样的道理,如果0day可能会出现,那最后必然会出现,只是时间和时机的问题。时间就是如果你的产品复杂些,或者对知识产品保护比较严格,那攻击方发现漏洞的时间可能会比较长。时机就是攻击方什么时候会利用这些漏洞(大家应该会快就会见识到)。
其实软件产品出现漏洞并不丢人,因为首先现在产品的代码和使用的第三方库越来越多,越来越复杂,再加上开发人员能力以及流动性,难免会出现错误引入漏洞。其次是攻击方和防守方能力和资源的不对等。这些安全产品在上线前肯定会经过渗透测试和代码审计,但是做这些事的人可能迫于上线的时间压力,没能全面深入地完成评估,或者因为个人技术经验的局限性,没能发现存在的问题,而真正挖掘安全产品漏洞并进行利用的人,却是各安全公司高级实验室优秀的研究人员,或者一些APT组织,而且时间也比较充裕。另外在攻防双方真正进入交战状态时,能力也是不对等的。攻击方可能是各安全公司最优秀的攻击团队,或者真实的APT组织,而防守方所谓的安全专家,可能是经过了三四层外包的实习生。
安全产品本来应该是企业防御的第一道防线,现在多数情况下却变成了攻击者进入企业的入口点。当然该做的事也都做了,比如渗透测试,代码审计,及时更新补丁,做的好不多先另说,但与此同时,我们也应该换个思路进行防御体系的建设。
“防御是理想的,但检测是必须的”,如果你安全建设的目标是为了不发生入侵事件,那你已经失败了;如果安全产品希望通过各种流程、规范来杜绝漏洞的出现,那也必然会失败。所以我们应该考虑,既然0day一定会出现,那在0day被发现和利用的时候,我们能否检测到?安全产品是否有相应的检测机制来检测自身被入侵?(对于参加了多次攻防演练人,心里应该有答案了)
下面就介绍下如何通过欺骗的思路,检测主机的失陷。当然只是抛砖引玉,我相信国内安全公司那么多优秀的专业人员,只要想解决这类问题,肯定能想出更优雅的方案的。或者已经存在更优雅的方案,只是我不知道,如果有的话,也希望大家可以分享下。
攻击者不论通过何种方式进入我们的网络,目标其实无非是数据或者进行破坏(目前多数还是以数据为目标)。那我们就可以通过部署诱饵文件的方式,来检测系统被入侵。
在下面的例子中,我们使用python的inotify库监控root用户家目录下的两个ssh私钥文件'ssh_key_132'和'ssh_key_148'的访问,因为这两个文件正常情况下不会被访问,一旦被访问,则能判断主机已失陷,然后通过飞书的机器人进行告警,当然也可以使用其他机器人,比如企微机器人,钉钉机器人,或者通过SIEM平台。
对于一些业务系统可能存在防病毒产品会扫描系统文件的情况,从而产生误报,所以需要提前加白。但安全产品多数不会安装防病毒产品。
要创建ssh诱饵私钥,我们可以使用ssh-keygen,然后使用下面的脚本监控文件的访问:
# pip install inotify
# pip install requests
import inotify.adapters
import json
import requests
webhook = 'https://open.feishu.cn/open-apis/bot/v2/hook/9a......5'
def send_msg(url,msg):
json_header = {"Content-Type": "application/json"}
data = {"msg_type":"post",
"content":{
"post": {
"zh_cn": {
"title":"Honey SSH Key was accessed!!",
"content": [
[
{ "tag":"text",
"text":"FileName: "
},
{
"tag": "text",
"text": msg['file']
}
]
]
}
}
}
}
try:
r = requests.post(url,data=json.dumps(data).encode('utf-8'),headers=json_header)
#print(r.text)
except Exception as err:
#print(err)
pass
def watch(path,honey_file):
i = inotify.adapters.Inotify()
i.add_watch(path)
for event in i.event_gen(yield_nones=False):
(_, type_names, path, filename) = event
print(type_names)
if filename in honey_file and 'IN_OPEN' in type_names:
msg = {'file':filename}
#print("PATH=[{}] FILENAME=[{}] EVENT_TYPES={}".format(
# path, filename, type_names))
send_msg(webhook,msg)
if __name__ == '__main__':
path = "/root/.ssh/"
honey_file = ['ssh_key_132','ssh_key_148']
watch(path,honey_file)
python3.8 -m nuitka --onefile --clean-cache=all --company-name=Linux --product-name=linux --file-version=1.0.1 --product-version=1.0.1 --file-description='Linux daemon process' --copyright='© 2023 Canonical Ltd. Ubuntu and Canonical are registered trademarks of Canonical Ltd.' --output-filename=SecWatch SecWatch.py
接下来我们需要监控程序开机自动运行,这里使用创建服务的方式,当然也有其他的一些方式。先将编译好的程序复制到/usr/local/bin目录:
cp SecWatch /usr/local/bin/
最后创建一个服务配置文件/etc/systemd/system/SecWatch.service:
touch /etc/systemd/system/SecWatch.service
chmod 644 /etc/systemd/system/SecWatch.service
/etc/systemd/system/SecWatch.service内容如下:
[Unit]
Description=SecWatch
After=network.target
[Service]
ExecStart=/usr/local/bin/SecWatch
[Install]
WantedBy=multi-user.target
启用并启动服务:
systemctl enable SecWatch.service
systemctl start SecWatch.service
查看服务状态:
当服务正常运行后,我们可以访问诱饵文件进行测试:
可以看到,当诱饵文件被访问后,我们就能第一时间收到告警。
上面只是监控ssh私钥的例子,但是实际场景对于要监控的文件的选择可能需要结合应用场景来选择,比如如果应用对外只开放了443端口,且运行权限是www-data,那诱饵文件优先选择www-data有权限访问的文件和目录,当然也可以根据不同的权限和用户,多部署几个诱饵。
上面主要是提出安全产品目前缺少自身的防御和检测机制的现状,以及利用欺骗进行检测的思路。关于欺骗技术的应用,大家也可以参考之前的一篇文章:主动防御&网络欺骗:让网络防御成为一种艺术
最近刚看了《长空之王》这部电影,个人感觉还是挺不错的。其实网络安全领域和军事领域类似,也是落后于国外,也面临技术封锁(比如微软的ATP,现在为MDI,就对中国大陆限制出口)。但是区别在于军事领域国外战机不会帮你骗自己,不会用PPT和EXCEL表格来证明你的战斗机很先进。而网络安全领域就不同了,我们可以自己骗自己,或者帮助一些既得利益者骗自己。就如前段时间公开的十几年前国外APT组织对我们某个大学的攻击一样,反正都落后了十几年了,现在这样玩,大不了落后个二三十年又如何,反正我们总能找到理由和借口。
但是,作为安全从业人员,难道真的做不了什么吗?我相信还是可以做些什么的。只希望真正热爱这个行业的人不要忘记初心。这里我举个例子,比如要给客户发一份报告,客户第二天10点以后上班才会看,那我们就没必要下班以后发。有人可能想让领导觉得工作很认真,下班也在干活,但长此以往,别人就会认为下班加班是理所当然的事。当然我不是说下班后什么都不管,紧急的事比如应急响应,还是需要处理,但这是合理的。
所以要做出改变,并不需要你成为CSO或者技术总监,在力所能及的范围内做出点什么,总比找借口强。希望安全行业的兄弟们能够站着为客户解决问题,实现自己理想的同时也能养家糊口,而不是跪着连汤都喝不上😈。
最后,也希望各安全公司能对自己的产品加入上述的能力,不仅可以检测入侵活动,也可以检测代码是否被破解,来保护知识产权。大家在采购安全产品时,也可以将安全产品能否检测自己被入侵作为一个评估项,并进行评估,而不要过度相信投标书和白皮书里面的参数。