1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*- 3 4 """ 网络数据包捕获与分析程序 """ 5 6 import pcap 7 import dpkt 8 import json 9 import re 10 import time 11 from urllib import unquote 12 13 # 过滤输出目标ip 14 dst_lists = [ 15 '203.66.1.212', # nslookup dpdcs.4399sy.com.hk 16 '52.74.10.186', # nslookup dpdcs.4399en.com 17 '52.58.69.212', # nslookup dpdcs.4399sy.ru 18 '220.241.11.3', # nslookup dpdcs.4399th.com 19 '124.243.195.63', # nslookup sdkdcs.4399sy.com 20 '42.62.106.216', # nslookup udpdcs.4399sy.com 21 '42.62.106.230', # nslookup udpdcs.4399sy.com 22 ] 23 24 req_data = "" 25 times = 0 26 27 28 def capt_data(eth_name="eth0", p_type=None): 29 """ 30 捕获网卡数据包 31 :param eth_name 网卡名,eg. eth0,eth3... 32 :param p_type 日志捕获类型 1:sdk日志用例分析 2:目标域名过滤输出 3:原始数据包 33 :return: 34 """ 35 36 pc = pcap.pcap(eth_name) 37 pc.setfilter('tcp port 80') # 设置监听过滤器 38 print 'start capture....' 39 if pc: 40 for p_time, p_data in pc: # p_time为收到时间,p_data为收到数据 41 anly_capt(p_time, p_data, p_type) 42 43 44 def anly_capt(p_time, p_data, p_type): 45 """ 46 解析数据包 47 :param p_data 收到数据 48 :param p_type 日志捕获类型 1:sdk日志用例分析 2:目标域名过滤输出 3:原始数据包 49 :return: 50 """ 51 52 p = dpkt.ethernet.Ethernet(p_data) 53 if p.data.__class__.__name__ == 'IP': 54 ip_data = p.data 55 src_ip = '%d.%d.%d.%d' % tuple(map(ord, list(ip_data.src))) 56 dst_ip = '%d.%d.%d.%d' % tuple(map(ord, list(ip_data.dst))) 57 if p.data.data.__class__.__name__ == 'TCP': 58 tcp_data = p.data.data 59 if tcp_data.dport == 80: 60 # print tcp_data.data 61 if tcp_data.data: 62 # 调用日志模块,对日志进行处理 63 if p_type == 1: 64 # sdk日志用例分析 65 if dst_ip in dst_lists: 66 tmp = tcp_data.data.strip() 67 global req_data, times 68 if tmp.startswith("POST") or tmp.startswith("GET"): # or times > 0 69 if req_data: 70 haiwai_log_case(req_data) 71 req_data = tmp + " " 72 # times = 0 73 else: 74 req_data = req_data + tmp 75 # times = times + 1 76 77 elif p_type == 2: 78 # 目标域名过滤输出 79 if dst_ip in dst_lists: 80 print "tcp_data:", tcp_data.data 81 82 else: 83 # 无过滤条件输出 84 print "tcp_data:", tcp_data.data 85 86 87 # android 日誌類型,从data中获取 88 log_type_from_data = { 89 90 'open_game': u'[打开游戏]', 91 'network_check': u'[网络监测]', 92 'open_login': u'[登录界面前]', 93 'select_server': u'[选服日志]', 94 'create_role': u'[创角日志]', 95 'role_level_change': u'[等级日志]', 96 97 # 海外,俄语 98 'activity_open': u'[打开游戏]', 99 'load_start_before_login': u'[加载开始]', 100 'load_finish_before_login': u'[加载结束]', 101 'activity_before_login': u'[登录界面前]', 102 'click_enter': u'[进入游戏]', 103 'get_user_server_login': u'[选服日志]', 104 'user_create_role': u'[创角日志]', 105 'role_login': u'[角色登录]', 106 'enter_success': u'[成功进入游戏]', 107 'role_level': u'[等级日志]', 108 'user_online': u'[在线日志]', 109 'exit_success': u'[退出游戏]', 110 111 } 112 113 # ios日誌類型,从请求资源路径获取 114 log_type_from_path = { 115 'activity_open.php': u'[打开游戏]', 116 'load_start_before_login.php': u'[加载开始]', 117 'load_finish_before_login.php': u'[加载结束]', 118 'activity_before_login.php': u'[登录界面前]', 119 'click_enter.php': u'[进入游戏]', 120 'get_user_server_login.php': u'[选服日志]', 121 'user_create_role.php': u'[创角日志]', 122 'role_login.php': u'[角色登录]', 123 'enter_success.php': u'[成功进入游戏]', 124 'user_online.php': u'[在线日志]', 125 'role_level.php': u'[等级日志]', 126 'exit_success.php': u'[退出游戏]', 127 'share.php': u'[分享日志]', 128 'init_info.php': u'[初始化日志]', 129 'event.php': u'[事件日志]', 130 'user_login.php': u'[user_login]', 131 'user_server_login.php': u'[user_server_login]', 132 'enter_game.php': u'[enter_game]', 133 } 134 135 # 过滤path 136 filter_out_list = [ 137 'u/', 138 'plugin/error/check', 139 'service/version/get_info', 140 ] 141 142 # 过滤打印出属于列表中的host的日志。 143 host_list = [ 144 'dpdcs.4399sy.com.hk', 145 'dpdcs.4399en.com', 146 'dpdcs.4399sy.ru', 147 'dpdcs.4399th.com', 148 'sdkdcs.4399sy.com', 149 'udpdcs.4399sy.com', 150 ] 151 152 153 def formattime(t): # 日期字段格式化 154 return time.strftime('%c', time.gmtime(t + 8 * 3600)) 155 156 157 def req_to_dict(req_string): 158 """ 159 将请求数据转换为dic 160 :param req_string: 161 :return: 162 """ 163 req_dict = {} 164 req_string = req_string.strip() 165 if len(req_string) > 0: 166 req_string = unquote(req_string) 167 # print "req_string_after_unquote:",req_string 168 m1 = re.search("(GET|POST)(.*)?(.*)HTTP/1.1", req_string) # (method,path,param) 169 m2 = re.search("Host:(.*)", req_string) # (host,) 170 # m3 = re.search("sdata=(.*)s", req_string) # (body,) 171 m4 = re.search("sdata=([sS]*)", req_string) # (body,) 172 # m5 = re.search("eventTime":"(d+)", req_string) # (eventTime,) 173 m5 = re.search("eventTime"s*:s*"(d+)", req_string) 174 if m1: 175 req_dict["method"] = m1.group(1).strip() 176 req_dict["path"] = m1.group(2).strip()[1:] 177 param_string = m1.group(3).strip() 178 if param_string: 179 param_string = param_string.split("&") 180 param_dict = {} 181 for item in param_string: 182 tmp_list = item.split("=") 183 if len(tmp_list) > 1: 184 param_dict[tmp_list[0]] = tmp_list[1] 185 req_dict["param"] = param_dict 186 if m2: 187 req_dict["host"] = m2.group(1).strip() 188 if m4: 189 try: 190 body = m4.group(1).replace(" ", "") 191 body = json.loads(body) 192 except ValueError: 193 print "