企业微信告警和回调

作者 折戟 日期 2019-04-15
企业微信告警和回调

企业微信告警和回调


最近正在参与一次护网行动,学到很多东西,等这次结束再来好好谈谈收获和总结吧,这都是后话了。这次主要分享一下企业微信的告警以及回调的实现以及踩的坑。
先说说前因后果吧,在护网行动正式开打之前,我们对xx公司也进行详细的网络情况了解,以及合作梳理。具体之后再说,反正结论就是网络边界的梳理和整顿都已经弄得比较不错了,唯一存在问题的就是在一些waf以及ids的告警上,因为策略全部default开启,导致出现大量的告警情况,为对攻击的分析以及响应带来很多麻烦,因此我们一部分工作在整理和梳理网络告警的方面。
他们一共有三个网络告警的设备,防火墙,ids,F5等,都是通过同一个zabbix发送请求到告警平台进行告警。于是我们在阿里云上建立了一个soc(安全运营中心),上面搭了elk,zabbix将三个网络告警全部发送到这个elk上……..之后再说。最后将soc上整理之后的告警发送到企业微信,并达到通过在企业微信上回复消息,对ip进行增删黑名单的操作。
企业微信回调过程:

  1. 创建企业微信应用:登录企业微信->应用与小程序->自建->创建应用
  2. 创建了之后
    111
    设置api接收进行。设置api接收时需要进行回调验证,部署好后面那个回调代码就行。
    发送告警很简单。根据企业微信给的api文档说明以及示例代码可以写出来。我这里用的是python3:
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # @Time : 2019/6/2
    # @Author : XDN01
    # @Site : www.raosong.cc
    # @File : sent_wexin.py
    #-*- coding:utf-8 -*-
    from flask import Flask,request
    import json
    import requests

    app = Flask(__name__)
    @app.route('/getmsg',methods=['POST'])
    def index():
    corpid = "xxxxxxxxxxx"
    secret = "xxxxxxxxxxxxxxxx"
    agentid = "xxxxxxxxx"
    #if request.method == 'GET':
    # return 'Deny'
    #接收POST的数据
    if request.method == 'POST':
    if request.form.get('checkid') == 'checkid': # 校验的id,避免有人恶意发送
    GetMsg = request.form.get('msg')
    print(GetMsg)
    wechat = WeChat(corpid, secret, agentid)
    if wechat.send_message(GetMsg) == 1:
    return 'Sent to weixin successed'
    else:
    return 'Failed'
    else:
    return 'Deny'

    class WeChat(object):
    def __init__(self, corpid, secret, agentid):
    self.url = "https://qyapi.weixin.qq.com"
    self.corpid = corpid
    self.secret = secret
    self.agentid = agentid

    # 获取企业微信的 access_token
    def access_token(self):
    url_arg = '/cgi-bin/gettoken?corpid={id}&corpsecret={crt}'.format(
    id=self.corpid, crt=self.secret)
    url = self.url + url_arg
    response = requests.get(url=url)
    text = response.text
    self.token = json.loads(text)['access_token']

    # 构建消息格式
    def messages(self, msg):
    values = {
    "touser": '@all',
    # "toparty" : "PartyID1|PartyID2", # 向这些部门发送 #'@all'给所有的发
    "msgtype": 'text',
    "agentid": self.agentid,
    "text": {'content': msg},
    "safe": 0
    }
    self.msg = (bytes(json.dumps(values), 'utf-8'))


    # 发送信息
    def send_message(self, msg):
    self.access_token()
    self.messages(msg)
    send_url = '{url}/cgi-bin/message/send?access_token={token}'.format(url=self.url, token=self.token)
    response = requests.post(url=send_url, data=self.msg)
    errcode = json.loads(response.text)['errcode']
    if errcode == 0:
    return 1
    else:
    return 0

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

下面是用户将数据发送给企业微信上的应用,回调发送到soc上进行记录,这里是记录在文件中:

#-*- coding:utf-8 -*-
from flask import Flask,request
from WXBizMsgCrypt import WXBizMsgCrypt
import xml.etree.cElementTree as ET
import sys
from RedisUtil import RedisUtil
app = Flask(__name__)
@app.route('/weixin', methods=['GET','POST'])
def index():
sToken = 'xxxxxxxx'
sEncodingAESKey = 'xxxxxxxxxxxxxxxxx'
sCorpID = 'xxxxxxxxxxxx'
wxcpt=WXBizMsgCrypt(sToken,sEncodingAESKey,sCorpID)

#获取url验证时微信发送的相关参数
sVerifyMsgSig=request.args.get('msg_signature')
sVerifyTimeStamp=request.args.get('timestamp')
sVerifyNonce=request.args.get('nonce')
sVerifyEchoStr=request.args.get('echostr')
#
sReqMsgSig = sVerifyMsgSig
sReqTimeStamp = sVerifyTimeStamp
sReqNonce = sVerifyNonce
#
sResqMsgSig = sVerifyMsgSig
sResqTimeStamp = sVerifyTimeStamp
sResqNonce = sVerifyNonce
#验证url
if request.method == 'GET':
ret,sEchoStr=wxcpt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp,sVerifyNonce,sVerifyEchoStr)
if (ret != 0 ):
print("ERR: VerifyURL ret:",ret)
sys.exit(1)
return sEchoStr

#接收客户端消息
if request.method == 'POST':
sReqMsgSig = sVerifyMsgSig
sReqTimeStamp = sVerifyTimeStamp
sReqNonce = sVerifyNonce
sReqData = request.data

ret,sMsg=wxcpt.DecryptMsg( sReqData, sReqMsgSig, sReqTimeStamp, sReqNonce)
if (ret != 0):
print("ERR: VerifyURL ret:")
sys.exit(1)

#解析发送的内容
xml_tree = ET.fromstring(sMsg)
content = xml_tree.find("Content").text

print(content)
#将接收到的内容记录在文件当中
f1 = open('weixin_soc_get.txt', 'a')
f1.writelines(content+"\n")
f1.close()
return "OK" # 默认发送三次 ,接收到ok之后就不会重复发送

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

直接更改代码中的token和企业id什么的就能直接用,具体的可以参考官方文档https://work.weixin.qq.com/api/doc
以及官方github库https://github.com/sbzhu/weworkapi_python
带上官方这里给的是python2的,而且给的代码库还会有一些问题,主要就是WXBizMsgCrypt.py这个文件,具体的我已经进行更改,在我的github项目中,可以直接替换就行:https://github.com/rliyuqing/weworkapi_py3
回调和发送信息创建的webserver用nginx代理就行,十分方便:
nginx代理
统一端口开放很重要的。其他的内容下次在分享,主要刚刚把企业微信告警的来回的两条线走通,所以记录分享一下。