OpenRASP报警推送

× 文章目录
  1. 1. 0x00 前言
  2. 2. 0x01 坎坷
  3. 3. 0x02 好像瞧见了光明
  4. 4. 0x03 柳暗花明
  5. 5. 0x04 结果

0x00 前言

OpenRASP 上线一周了,运行很稳定,拉了几个PHP和Java做测试,没有收到业务方的异常反馈,除了我测试的报警外,只发现一些基线的报警,找运维都处理了。

随着运营时间,后续安全基线问题不应该存在了,重点关注一下攻击事件,系统设置中有报警推送功能,有邮件报警、HTTP报警推送、钉钉集成、syslog报警

我们目前使用的IM是企业微信,企业微信群机器人推送消息使用很方便,我们把很多告警邮件类都修改为群机器人通知了,把RASP也修改一下吧

0x01 坎坷

OpenRASP 管理后台使用GO语言开发的,从菜鸟教程上浏览了下go的基础语法,开始搞,因为只是加个报警推送,就不修改前端了

从Github上把源码下载下来,有点大

看下目录结构 openrasp\cloud\src\rasp-cloud MVC模型,业务逻辑应该都在models 文件里, 打开app.go

找到钉钉推送的函数PushDingAttackAlarm, 复制一个按照企业微信群机器人的消息格式修改一下

群机器人消息格式

1
2
3
4
5
6
{
"msgtype": "markdown",
"markdown": {
"content": "content"
}
}

找到PushAttackAlarm 修改一下

然后编译 – 上传测试服务器 – 测试报警失败 – 继续修改 – 编译 – 上传测试服务器 – 测试失败 ……

不知道试了多少次,json数据就是处理不好

0x02 好像瞧见了光明

不好搞,回头看了下,自带的报警有一个HTTP报警推送,拿Python flask写一个服务做中转,接收报警消息,一个json格式字符串

那就好办了,处理下数据,测试环境发送给群机器人成功

群机器人配置一定要开启推送消息IP白名单,不配置则任何IP都可调用,防止泄露被恶意调用

把脚本放到线上IDC,what,IDC是禁止请求公网的

0x03 柳暗花明

之前运维开发了一个企业微信通知应用的内网API调用接口,可以使用这个接口将报警推送到企业微信

下面附上代码(代码写的有点乱,修改的话可以把这个接口换成机器人)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# -*- encoding: utf-8 -*-
from flask import Flask, request, jsonify
import requests

app = Flask(__name__)
@app.route('/alert', methods=['POST'])
def alert():
try:
log = request.json
# print(log["data"][0])

if 'server_nic' not in log["data"][0].keys(): # 这里做了异常处理,cmdb接口不能为空,不能为127.0.0.1
# print("ip不存在")
systemName = "请登录后台查看"
firstMan = "请登录后台查看"
else:
ip = log["data"][0]["server_nic"][0]['ip'].encode("utf8")
# print(type(ip)) # ip类型为unicode,需要做编码转换
if ip == "127.0.0.1":
systemName = "请登录后台查看"
firstMan = "请登录后台查看"
else:
try:
data = { "ip": ip }
headers = { "Host": "{cmdb}" } # 运维那边的cmdb系统,查询资产信息的,可以去掉
rep = requests.post("http://{cmdb}/api/", data = data, headers = headers, timeout=2)
# print rep.text
if rep.text:
content = rep.text.split("\n")
for con in content:
if con.startswith(u"系统名称"):
systemName = con.split(":")[1].encode('utf8')
if con.startswith(u"第一负责人"):
firstMan = con.split(":")[1].encode('utf8')
except Exception as e:
# print e
systemName = "请登录后台查看"
firstMan = "请登录后台查看"

content = """
RASP发现攻击成功告警
报警时间:{time}
攻击类型:{attack}
攻击源IP地址:{source}
目的URL:{url}
系统名称:{sys}
第一负责人:{m}
""".format(time=log['data'][0]['event_time'],attack=log['data'][0]['attack_type'],source=log['data'][0]['attack_source'],url=log['data'][0]['url'],sys=systemName, m=firstMan)
# print(content)
log_file = open('./alert.log','a')
log_file.write(content)
log_file.close()
user = "user1|user2"
weixin = "http://{}/wxchat?user={0}&content={1}&token={}".format(user, content) # api接口,可以换成群里机器人webhook,需要微调下content格式
r = requests.get(weixin, timeout=2)
return jsonify({'code': 1, 'message': 'sucess'})
except Exception as e:
return jsonify({'code': 0, 'message': str(e)})

if __name__ == '__main__':
# app.run(debug=True)
app.run(host='0.0.0.0', port=8888)

0x04 结果

以Java反序列化和Struts2-019远程命令执行漏洞为例,从json格式报警中找了event_time、attack_type、attack_source、url,其他关键字先忽略了

报警推送效果