Files
slpscan/libs/srvloc_main.py
2026-01-23 20:47:54 +01:00

268 lines
9.3 KiB
Python

import os
import sys
import json
import time
import socket
import threading
import argparse
from libs.srvloc_globals import q, rQ, __tool_author__, __tool_version__, __tool_date__, jout_Queue
from libs.srvloc_proto_v1 import *
from libs.srvloc_proto_v2 import *
from libs.srvloc_helper import randomizeIP, generate_randomIP, clean_line, check_blacklist
from libs.srvloc_log import printd, printe
from libs.srvloc_fortune import rnd_fck
def parser_main():
parser_desc = 'service location protocol {0} by {1} in {2}'.format(
__tool_version__, __tool_author__, __tool_date__)
prog_desc = 'slpscan.py'
parser = argparse.ArgumentParser(prog=prog_desc, description=parser_desc)
parser.add_argument("-l", "--host", action="store",
required=False, help='host to check version', dest='host')
parser.add_argument("-L", "--hostlist", action="store",
required=False, help='hostlist to check', dest='hostlist')
parser.add_argument("-p", "--port", action="store", required=False,
default=427, help='slp port (default:427)', dest='port')
parser.add_argument("-t", "--threads", action="store", required=False,
default=50, help='how many threads', dest='thrCnt', type=int)
parser.add_argument("-m", "--slp-mode", action="store", required=False, default='',
help='what attack mode to choose, ? for list', dest='slp_mode')
parser.add_argument("-P", "--probe-mode", action="store", required=False, default=False,
help='what probe to send, ? for list', dest='probe_mode')
parser.add_argument("-d", "--packet-delay", action="store", required=False, type=float,
help='set the delay(in seconds) a packet is sent, delay is per thread (1s and 10 threads, each second 10 threads are working)',
dest='pkt_delay')
parser.add_argument("-T", "--timeout", action="store", required=False,
default=5, help='timeout of socket recv', dest='timeout')
parser.add_argument("-o", "--outfile", action="store",
required=False, help='outfile in txt format', dest='outfile')
parser.add_argument("-oj", "--outfile-json", action="store",
required=False, help='outfile in json format', dest='outfile_json')
parser.add_argument("-r", "--unrandom", action="store", required=False,
help='disable random targetlist', dest='unrandom')
parser.add_argument("-R", "--randomIP", action="store", required=False,
help='generate random ips on the fly', dest='randomip')
args = parser.parse_args()
return args
SLP_SVC_REQ = 0x1
SLP_SVC_REPLY = 0x2
SLP_ATTR_REQ = 0x6
SLP_ATTR_REPLY = 0x7
SLP_SVC_TYPE_REQ = 0x9
SLP_SVC_TYPE_REPLY = 0xa
# FIXME build other structure for modes
def choose_slp_mode(args):
lsize = 70
modes = {1: {'name': '{0:<30} {1:<15} {2:<30}'.format('SLPv1 Modes', 'Operation', 'Description'), 'Operation': '', 'Description': '', 'Method': ''},
# 2: {'name': '-'*lsize, 'Operation': '', 'Description': '', 'Method': ''},
# !!!!!!
21: {'name': 'svc_req_v1', 'Operation': SLP_SVC_REQ, 'Description': '', 'Method': build_slp_svc_req_v1()},
22: {'name': 'svc_reply_v1', 'Operation': SLP_SVC_REPLY, 'Description': '', 'Method': build_slp_reply_v1()},
26: {'name': 'svc_attr_req_v1', 'Operation': SLP_ATTR_REQ, 'Description': '', 'Method': build_svc_attr_req_v1()},
27: {'name': 'svc_attr_reply_v1', 'Operation': SLP_ATTR_REPLY, 'Description': '', 'Method': build_slp_attr_reply_v1()},
29: {'name': 'svc_type_req_v1', 'Operation': SLP_SVC_TYPE_REQ, 'Description': '', 'Method': build_slp_svc_type_req_v1()},
30: {'name': 'svc_type_reply_v1', 'Operation': SLP_SVC_TYPE_REPLY, 'Description': '', 'Method': build_slp_type_reply_v1()},
38: {'name': '{0:<30} {1:<15} {2:<30}'.format('SLPv2 Modes', 'Operation', 'Description'), 'Operation': '', 'Description': '', 'Method': ''},
40: {'name': 'svc_req_v2', 'Operation': SLP_SVC_REQ, 'Description': '', 'Method': build_slp_svc_req_v2()},
41: {'name': 'svc_reply_v2', 'Operation': SLP_SVC_REPLY, 'Description': '', 'Method': build_slp_reply_v2()},
45: {'name': 'svc_attr_req_v2', 'Operation': SLP_ATTR_REQ, 'Description': '', 'Method': build_slp_attr_req_v2()},
46: {'name': 'svc_attr_reply_v2', 'Operation': SLP_ATTR_REPLY, 'Description': '', 'Method': build_slp_attr_reply_v2()},
48: {'name': 'svc_type_req_v2', 'Operation': SLP_SVC_TYPE_REQ, 'Description': '', 'Method': build_slp_svc_type_req_v2()},
49: {'name': 'svc_type_reply_v2', 'Operation': SLP_SVC_TYPE_REPLY, 'Description': '', 'Method': build_slp_type_reply_v2()},
}
slp_mode = args.slp_mode
if slp_mode == '?':
print()
for k in modes.keys():
# print(modes[k])
name = modes[k]['name']
operation = modes[k]['Operation']
desc = modes[k]['Description']
if name.startswith('SLPv'):
print('-'*lsize)
print('{0:<30} {1:<15} {2:<30}'.format(name, operation, desc))
if name.startswith('SLPv'):
print('-'*lsize)
print()
sys.exit()
else:
for k in modes.keys():
if slp_mode == modes[k]['name']:
pkt = modes[k]['Method']
return pkt
print('Unknown mode use -m? for showing supported modes')
sys.exit()
def make_request(host, port, args, pkt):
human = []
timeout = args.timeout
slp_mode = args.slp_mode
probe_mode = args.probe_mode
pkt_delay = args.pkt_delay
if pkt_delay:
time.sleep(pkt_delay)
try:
# build up socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# we want to have a timeout
s.settimeout(timeout)
s.connect((host, port))
# send the discovery packet
s.send(pkt)
# getting the data of the connection
rec = s.recv(4096)
data_dict = {'target': host+':' +
str(port), 'reply_pkt': rec, 'pkt': pkt}
hdata = '%s:%d' % (host, port)
hdump = '%s' % (repr(rec))
# place stuff in one of the queues
human.append(hdata)
human.append(hdump)
# human.append(reply_dict)
rQ.put(human)
except socket.timeout:
printe('%s timeout' % host)
except socket.error:
printe('%s refused' % host)
def run_mainthreads(args, pkt):
# wanna have a c00kie?!
fck = rnd_fck()
printd(fck)
if args.outfile:
fw = open(args.outfile, 'w')
if args.outfile_json:
fwj = open(args.outfile_json, 'w')
if args.host:
host = args.host
print('Hostmode: %s' % host)
line = clean_line(host)
bl = [host]
wh = check_blacklist(bl)
if len(wh) == 1:
q.put(line)
else:
# print('{0} Blacklisted!!!'.format(host))
sys.exit()
elif args.hostlist:
ipL = []
hostlist = args.hostlist
print('Hostlistmode')
fr = open(hostlist, 'r')
rBuf = fr.readlines()
for l in rBuf:
l = clean_line(l)
ipL.append(l)
if not args.unrandom:
iplist = randomizeIP(ipL)
else:
iplist = ipL
iplist = check_blacklist(iplist)
list = [q.put(query) for query in iplist]
elif args.randomip:
randIP = int(args.randomip)
print('RandomIPs: %d' % (randIP))
else:
print('Unknown or no mode choosen. cya')
sys.exit()
if not args.randomip:
print('Targets: %d' % (q.qsize()))
else:
# lets start the thread for generating randomIPs
printd('Starting random thread:')
randIPThread = threading.Thread(
target=generate_randomIP, args=(q, args.randomip))
randIPThread.daemon = True
randIPThread.start()
# FIXME
# quick fix so we do not miss the threading loop
# better would be a counter in the loop itself
time.sleep(5)
port = int(args.port)
thrCnt = args.thrCnt
thrList = []
printd('Starting loop')
while True:
if len(thrList) < thrCnt and q.qsize() > 0:
newthread = threading.Thread(target=make_request, args=(
q.get(), port, args, pkt))
newthread.daemon = True
newthread.start()
thrList.append(newthread)
for entry in thrList:
if entry.is_alive() == False:
entry.join()
thrList.remove(entry)
time.sleep(0.1)
if rQ.qsize() > 0:
pout = rQ.get()
pp = '%s' % (pout)
print('[RAW] ', pp)
print()
if args.outfile:
fw.write(pp + '\n')
if jout_Queue.qsize() > 0:
jdata = jout_Queue.get()
print(jdata)
if args.outfile_json:
fwj.write(jdata + '\n')
if q.qsize() == 0 and len(thrList) == 0:
break
def print_slp_modes():
data = '''
Supported modes:
* slp_type_request
requesting the supported ressources at the remote device
'''
print(data)