前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Python】QQ查IP工具

【Python】QQ查IP工具

作者头像
ITJoker
发布2022-08-30 11:27:26
1.7K0
发布2022-08-30 11:27:26
举报

根据wireshark分析可知,通过分析qq语音通话,发现采用的是dup协议(应该是叫这个) 检测数据包的标志020048即可 需要pypacp这个库,但是python3 的环境下,推荐pacp-ct 具体缺啥库就安装啥....

代码语言:javascript
复制
import psutil,netaddr,pcap,dpkt
import time
import platform
import binascii
 
if 'Windows' in platform.platform():
    import winreg as wr

FINGERPRINT = {
    'qq.exe':('udp','020048'),
    'tim.exe':('udp','020048')
}

IF_REG = r'SYSTEM\CurrentControlSet\Control\Network\{4d36e972-e325-11ce-bfc1-08002be10318}'

def get_interface_name(name):
    reg = wr.ConnectRegistry(None, wr.HKEY_LOCAL_MACHINE)
    reg_key = wr.OpenKey(reg, IF_REG)
    for i in range(wr.QueryInfoKey(reg_key)[0]):
        subkey_name = wr.EnumKey(reg_key, i)
        try:
            reg_subkey = wr.OpenKey(reg_key, subkey_name + r'\Connection')
            Name = wr.QueryValueEx(reg_subkey, 'Name')[0]
            wr.CloseKey(reg_subkey)
            if Name == name:
                return r'\Device\NPF_' + subkey_name
        except FileNotFoundError as e:
            pass
 
    return None

if 'Windows' in platform.platform():
    iface = get_interface_name('Router') # WLAN
else:
    iface = 'enp2s0'


def get_pid_sessions(is_show=True):
    sessions = {}
    for session in psutil.net_connections(kind="all"):
        if session.laddr and session.raddr:
            pid               = session.pid                                                                                                  #进程pid
            pid_name          = psutil.Process(int(pid)).name().lower()                                                                      #进程名
            pid_create_time   = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(psutil.Process(int(pid)).create_time()))                    #进程创建时间

            src_ip               = session.laddr.ip                                                                                          #源IP
            sport             = session.laddr.port                                                                                           #源端口
            des_ip               = session.raddr.ip                                                                                          #目的IP
            dport             = session.raddr.port                                                                                           #目的端口
            status            = session.status                                                                                               #会话状态

            filter_des_ip        = netaddr.IPAddress(des_ip)                                                                                             #格式化目的IP地址,用于后续判断是否是公网IP
            filter_src_ip        = netaddr.IPAddress(src_ip)
            if not filter_des_ip.is_private() and filter_des_ip.is_unicast() and not filter_des_ip.is_link_local() and not filter_src_ip.is_loopback():        #判断目的IP不是私网IP,是一个单播地址,不是linklocal地址,如果符合条件就记录  
                if pid_name not in sessions:
                    sessions[pid_name] = {}
                if pid not in sessions[pid_name]:
                    sessions[pid_name][pid] = {}
                if f'{src_ip}:{sport}' not in sessions[pid_name][pid]:
                    sessions[pid_name][pid][f'{src_ip}:{sport}'] = {}
                if f'{des_ip}:{dport}' not in sessions[pid_name][pid][f'{src_ip}:{sport}']:
                    sessions[pid_name][pid][f'{src_ip}:{sport}'][f'{des_ip}:{dport}'] = {
                        'create_time':'',
                        'status':''
                    }
                sessions[pid_name][pid][f'{src_ip}:{sport}'][f'{des_ip}:{dport}']['status'] = status
                sessions[pid_name][pid][f'{src_ip}:{sport}'][f'{des_ip}:{dport}']['create_time'] = pid_create_time
                if is_show:
                    print(f'[{pid_create_time}]  [{pid}]    [{pid_name}]   [{src_ip}:{sport}] ---> [{des_ip}:{dport}] ---- [{status}]')
    return sessions

def sniffer(pname):
    transport   = FINGERPRINT[pname][0]
    fingerprint = FINGERPRINT[pname][1]
    pc = pcap.pcap(iface, promisc=True, immediate=True)
    pc.setfilter(transport)
    if transport.lower() == 'tcp':
        check_transport = dpkt.tcp.TCP
    else:
        check_transport = dpkt.udp.UDP
    for timestamp, raw_buf in pc:
        eth = dpkt.ethernet.Ethernet(raw_buf)
        
        if not isinstance(eth.data, dpkt.ip.IP):
            continue
        df = bool(eth.data.off & dpkt.ip.IP_DF)
        mf = bool(eth.data.off & dpkt.ip.IP_MF)
        offset = eth.data.off & dpkt.ip.IP_OFFMASK
        traffic = eth.data.data
        if not isinstance(traffic,check_transport):
            continue
        if not len(traffic.data):
            continue
        packet =  {
            'time':time.strftime('%Y-%m-%d %H:%M:%S',(time.localtime(timestamp))),
            'src':'%d.%d.%d.%d'%tuple(eth.data.src), 
            'dst':'%d.%d.%d.%d'%tuple(eth.data.dst),
            'protocol':eth.data.p, 
            'len':eth.data.len, 
            'ttl':eth.data.ttl,
            'df':df, 
            'mf':mf, 
            'offset':offset, 
            'checksum':eth.data.sum,
            'traffic':binascii.b2a_hex(traffic.data).decode()
        }
        if packet['traffic'].startswith(fingerprint):
            print()
            for key in packet:
                length = len(key)
                ins_space_left  = ''
                ins_space_right = ''
                if length < 8:
                    ins_space_left  = ' ' * int((8-length)/2)
                    if length % 2:
                        ins_space_right = ' '* int((8-length)/2+1)
                    else:
                        ins_space_right = ' '* int((8-length)/2)
                print(f'[ {pname} ] [ {ins_space_left}{key}{ins_space_right} ] ----> {packet[key]}')
        else:
            print('\r[%s]  No capture!' %time.strftime('%Y-%m-%d %H:%M:%S',(time.localtime(time.time()))),end='')

if __name__ == "__main__":
    sessions = get_pid_sessions(False)
    pid_names = FINGERPRINT.keys()
    for pname in pid_names:
        if pname in sessions:
            sniffer(pname=pname)
            break
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-04-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
弹性公网 IP
弹性公网 IP(Elastic IP,EIP)是可以独立购买和持有,且在某个地域下固定不变的公网 IP 地址,可以与 CVM、NAT 网关、弹性网卡和高可用虚拟 IP 等云资源绑定,提供访问公网和被公网访问能力;还可与云资源的生命周期解耦合,单独进行操作;同时提供多种计费模式,您可以根据业务特点灵活选择,以降低公网成本。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档