Python - rpcinfo

In order to scan all rpc hosts in lannet and save it into the databse, we need to create a script.

  $ rpcinfo -p 192.168.1.24
   program vers proto   port
    100000    4   tcp    111  rpcbind
    100000    3   tcp    111  rpcbind
    100000    2   tcp    111  rpcbind
    100000    4   udp    111  rpcbind
    100000    3   udp    111  rpcbind
    100000    2   udp    111  rpcbind
    100024    1   udp  55265  status
    100024    1   tcp  42583  status
root@lab:~/# python rpcinfo.py 192.168.1.24
[{'program': 100000, 'protocol': '0x06,tcp', 'version': 4, 'port': 111}, {'program': 100000, 'protocol': '0x06,tcp', 'version': 3, 'port': 111}, {'program': 100000, 'protocol': '0x06,tcp', 'version': 2, 'port': 111}, {'program': 100000, 'protocol': '0x11,udp', 'version': 4, 'port': 111}, {'program': 100000, 'protocol': '0x11,udp', 'version': 3, 'port': 111}, {'program': 100000, 'protocol': '0x11,udp', 'version': 2, 'port': 111}, {'program': 100024, 'protocol': '0x11,udp', 'version': 1, 'port': 55265}, {'program': 100024, 'protocol': '0x06,tcp', 'version': 1, 'port': 42583}]

Code

#!/usr/bin/python
# -*- coding: utf-8 -

import socket
import struct
import time


class Service(object):
    def __init__(self):
        super(Service, self).__init__()

    def rpc_request(self):
        """Remote Procedure Call Request. If you want more, please use wireshark
        to capture (rpcinfo -p 192.168.1.100) packaets.
        """
        # Remote Procedure Call
        rpc_Fragment_header = 0x80000028
        rpc_XID = int(time.time())
        rpc_Message_Type = 0  # Call
        rpc_RPC_Version = 2
        rpc_Program = 100000  # Portmap
        rpc_Program_Version = 2
        rpc_Procedure = 4  # Dump
        rpc_Credentials_Flavor = 0  # AUTH_NULL
        rpc_Credentials_Length = 0
        rpc_Verifier_Flavor = 0  # AUTH_NULL
        rpc_Verifier_Length = 0

        # Portmap
        portmap_Program_Version = 2
        portmap_Procedure = 4 # Dump

        proto = struct.pack(
            # Remote Procedure Call
            '!LLLLLLLLLLLLL',
            rpc_Fragment_header,
            rpc_XID,
            rpc_Message_Type,
            rpc_RPC_Version,
            rpc_Program,
            rpc_Program_Version,
            rpc_Procedure,
            rpc_Credentials_Flavor,
            rpc_Credentials_Length,
            rpc_Verifier_Flavor,
            rpc_Verifier_Length,

            # portmap
            portmap_Program_Version,
            portmap_Procedure
        )

        return proto

    def parse_rpc_response(self, response):
        """parse Remote Procedure Call Reply.
        """
        rpc_map_entries = []

        if len(response) < 28:
            # Invalid rpc response
            return rpc_map_entries

        rpc = response[:28]
        (
            rpc_Fragment_header,
            rpc_XID,
            rpc_Message_Type,
            rpc_Reply_State,
            rpc_Verifier_Flavor,
            rpc_Verifier_Length,
            rpc_Accept_State
        ) = struct.unpack('!LLLLLLL', rpc)

        portmap = response[28:]
        if len(portmap) < 24:  # portmap_Value_Follows + one portmap_Map_entry
            return rpc_map_entries

        portmap_Value_Follows = portmap[0:4]
        portmap_Map_Entries = portmap[4:]

        portmap_Value_Follows = struct.unpack('!L', portmap_Value_Follows)
        portmap_Map_Entries = [
            portmap_Map_Entries[i:i+20]
            for i in range(0, len(portmap_Map_Entries), 20)
        ]

        for map_entry in portmap_Map_Entries:
            (
                program,
                version,
                protocol,
                port,
                value_follows
            ) = struct.unpack('!LLLLL', map_entry)

            if protocol == 0x06:
                protocol = '0x06,tcp'
            elif protocol == 0x11:
                protocol = '0x11,udp'
            else:
                protocol = '{},unknown'.format(protocol)

            _ = {
                'program': program, 'version': version,
                'protocol': protocol, 'port': port
            }
            if _ not in rpc_map_entries:
                rpc_map_entries.append(_)

        return rpc_map_entries

    def get_finger(self, host):
        banner = None

        buffersize=1024
        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        client.settimeout(4.0)
        try:
            client.connect((host, 111))
            client.send(self.rpc_request())
            rpc_response = client.recv(buffersize)
            print(self.parse_rpc_response(rpc_response))
        except Exception as err:
            print(err)
        finally:
            client.close()


if __name__ == '__main__':
    import sys

    rpc = Service()
    rpc.get_finger(sys.argv[1])
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值