mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-18 20:49:28 +00:00
71 lines
6.6 KiB
Python
71 lines
6.6 KiB
Python
# Provenance: stamparm/DSVW do_GET (fixed).
|
|||
|
|
# repo: stamparm/DSVW
|
||
|
|
# commit: 7d40f4b7939c901610ed9b85724552d60e7d63fa
|
||
|
|
# parent: 7d40f4b7939c901610ed9b85724552d60e7d63fa
|
||
|
|
# commit_url: https://github.com/stamparm/DSVW/blob/7d40f4b7939c901610ed9b85724552d60e7d63fa/dsvw.py#L30
|
||
|
|
# cve:
|
||
|
|
# license: Unlicense
|
||
|
|
# function: do_GET
|
||
|
|
# relpath: dsvw.py
|
||
|
|
# provenance: human
|
||
|
|
# mechanism: source_reaches_sink
|
||
|
|
|
||
|
|
def do_GET(self):
|
||
|
|
path, query = self.path.split('?', 1) if '?' in self.path else (self.path, "")
|
||
|
|
code, content, params, cursor = http.client.OK, HTML_PREFIX, dict((match.group("parameter"), urllib.parse.unquote(','.join(re.findall(r"(?:\A|[?&])%s=([^&]+)" % match.group("parameter"), query)))) for match in re.finditer(r"((\A|[?&])(?P<parameter>[\w\[\]]+)=)([^&]+)", query)), connection.cursor()
|
||
|
|
try:
|
||
|
|
if path == '/':
|
||
|
|
if "id" in params:
|
||
|
|
cursor.execute("SELECT id, username, name, surname FROM users WHERE id=" + params["id"])
|
||
|
|
content += "<div><span>Result(s):</span></div><table><thead><th>id</th><th>username</th><th>name</th><th>surname</th></thead>%s</table>%s" % ("".join("<tr>%s</tr>" % "".join("<td>%s</td>" % ("-" if _ is None else _) for _ in row) for row in cursor.fetchall()), HTML_POSTFIX)
|
||
|
|
elif "v" in params:
|
||
|
|
content += re.sub(r"(v<b>)[^<]+(</b>)", r"\g<1>%s\g<2>" % params["v"], HTML_POSTFIX)
|
||
|
|
elif "object" in params:
|
||
|
|
content = str(pickle.loads(params["object"].encode()))
|
||
|
|
elif "path" in params:
|
||
|
|
content = (open(os.path.abspath(params["path"]), "rb") if not "://" in params["path"] else urllib.request.urlopen(params["path"])).read().decode()
|
||
|
|
elif "domain" in params:
|
||
|
|
content = subprocess.run("nslookup " + params["domain"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, text=True).stdout
|
||
|
|
elif "xml" in params:
|
||
|
|
content = lxml.etree.tostring(lxml.etree.parse(io.BytesIO(params["xml"].encode()), lxml.etree.XMLParser(load_dtd=True, resolve_entities=True, no_network=False)), pretty_print=True).decode()
|
||
|
|
elif "name" in params:
|
||
|
|
found = lxml.etree.parse(io.BytesIO(USERS_XML.encode())).xpath(".//user[name/text()='%s']" % params["name"])
|
||
|
|
content += "<b>Surname:</b> %s%s" % (found[-1].find("surname").text if found else "-", HTML_POSTFIX)
|
||
|
|
elif "size" in params:
|
||
|
|
start, _ = time.time(), "<br>".join("#" * int(params["size"]) for _ in range(int(params["size"])))
|
||
|
|
content += "<b>Time required</b> (to 'resize image' to %dx%d): %.6f seconds%s" % (int(params["size"]), int(params["size"]), time.time() - start, HTML_POSTFIX)
|
||
|
|
elif "comment" in params or query == "comment=":
|
||
|
|
if "comment" in params:
|
||
|
|
cursor.execute("INSERT INTO comments VALUES(NULL, '%s', '%s')" % (params["comment"], time.ctime()))
|
||
|
|
content += "Thank you for leaving the comment. Please click here <a href=\"/?comment=\">here</a> to see all comments%s" % HTML_POSTFIX
|
||
|
|
else:
|
||
|
|
cursor.execute("SELECT id, comment, time FROM comments")
|
||
|
|
content += "<div><span>Comment(s):</span></div><table><thead><th>id</th><th>comment</th><th>time</th></thead>%s</table>%s" % ("".join("<tr>%s</tr>" % "".join("<td>%s</td>" % ("-" if _ is None else _) for _ in row) for row in cursor.fetchall()), HTML_POSTFIX)
|
||
|
|
elif "include" in params:
|
||
|
|
backup, sys.stdout, program, envs = sys.stdout, io.StringIO(), (open(params["include"], "rb") if not "://" in params["include"] else urllib.request.urlopen(params["include"])).read(), {"DOCUMENT_ROOT": os.getcwd(), "HTTP_USER_AGENT": self.headers.get("User-Agent"), "REMOTE_ADDR": self.client_address[0], "REMOTE_PORT": self.client_address[1], "PATH": path, "QUERY_STRING": query}
|
||
|
|
exec(program, envs)
|
||
|
|
content += sys.stdout.getvalue()
|
||
|
|
sys.stdout = backup
|
||
|
|
elif "redir" in params:
|
||
|
|
content = content.replace("<head>", "<head><meta http-equiv=\"refresh\" content=\"0; url=%s\"/>" % params["redir"])
|
||
|
|
if HTML_PREFIX in content and HTML_POSTFIX not in content:
|
||
|
|
content += "<div><span>Attacks:</span></div>\n<ul>%s\n</ul>\n" % ("".join("\n<li%s>%s - <a href=\"%s\">vulnerable</a>|<a href=\"%s\">exploit</a>|<a href=\"%s\" target=\"_blank\">info</a></li>" % (" class=\"disabled\" title=\"module 'python-lxml' not installed\"" if ("lxml.etree" not in sys.modules and any(_ in case[0].upper() for _ in ("XML", "XPATH"))) else "", case[0], case[1], case[2], case[3]) for case in CASES)).replace("<a href=\"None\">vulnerable</a>|", "<b>-</b>|")
|
||
|
|
elif path == "/users.json":
|
||
|
|
content = "%s%s%s" % ("" if not "callback" in params else "%s(" % params["callback"], json.dumps(dict((_.findtext("username"), _.findtext("surname")) for _ in xml.etree.ElementTree.fromstring(USERS_XML).findall("user"))), "" if not "callback" in params else ")")
|
||
|
|
elif path == "/login":
|
||
|
|
cursor.execute("SELECT * FROM users WHERE username='" + re.sub(r"[^\w]", "", params.get("username", "")) + "' AND password='" + params.get("password", "") + "'")
|
||
|
|
content += "Welcome <b>%s</b><meta http-equiv=\"Set-Cookie\" content=\"SESSIONID=%s; path=/\"><meta http-equiv=\"refresh\" content=\"1; url=/\"/>" % (re.sub(r"[^\w]", "", params.get("username", "")), "".join(random.sample(string.ascii_letters + string.digits, 20))) if cursor.fetchall() else "The username and/or password is incorrect<meta http-equiv=\"Set-Cookie\" content=\"SESSIONID=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT\">"
|
||
|
|
else:
|
||
|
|
code = http.client.NOT_FOUND
|
||
|
|
except Exception as ex:
|
||
|
|
content = ex.output if isinstance(ex, subprocess.CalledProcessError) else traceback.format_exc()
|
||
|
|
code = http.client.INTERNAL_SERVER_ERROR
|
||
|
|
finally:
|
||
|
|
self.send_response(code)
|
||
|
|
self.send_header("Connection", "close")
|
||
|
|
self.send_header("X-XSS-Protection", "0")
|
||
|
|
self.send_header("Content-Type", "%s%s" % ("text/html" if content.startswith("<!DOCTYPE html>") else "text/plain", "; charset=%s" % params.get("charset", "utf8")))
|
||
|
|
self.end_headers()
|
||
|
|
self.wfile.write(("%s%s" % (content, HTML_POSTFIX if HTML_PREFIX in content and GITHUB not in content else "")).encode())
|
||
|
|
self.wfile.flush()
|