waelmas / frameless-bitb

A new approach to Browser In The Browser (BITB) without the use of iframes, allowing the bypass of traditional framebusters implemented by login pages like Microsoft and the use with Evilginx.
BSD 3-Clause "New" or "Revised" License
338 stars 40 forks source link

BiB window gets blank instead of going to the KMSI page #5

Open par-retest opened 7 months ago

par-retest commented 7 months ago

Hi!

I'm having trouble reaching the KMSI part of the flow (for a company account) - after I enter my microsoft password, the entire page seems to refresh (I'm not 100% sure about that), and the BiB window is redrawn, this time blank (see screenshot).

2024-02-16-105400_926x871_scrot

The window title is "/login/common", and actually using this as obfEnd (const obfEnd = 'OBFSul2Zvx2Lu9Wbt92YEND';) works, but it again feels like a hotfix more than addressing the root cause. What do you think?

waelmas commented 7 months ago

Thanks for reporting this!

Indeed the current approach relies on the target path to know that the flow was completed, which should close the window and unlock the calendly widget. That's why changing the obfEnd (aka targetPath) solves this issue.

There are 2 approaches here: 1: Simply make the target path an array and if any of the target paths are seen, treat it as the end of the flow (Easy approach) 2: Check the cookies that are being set and when the auth cookies are all seen, treat it as the end of the flow (similar approach to what Evilginx natively does)

My plan was to work on the cookies approach in the pro version as that will be based on a custom proxy instead of apache, which allows full control and intercepting things before they reach the browser (removing that refresh effect too). But will look into it and see if it can be made on the client in an easy way.

The refresh you sometimes notice is expected as with each login flow redirect, we are injecting the HTML/CSS/JS again, and JS constructs most of the page in real time. With caching enabled on Apache, if the internet connection is not too slow and if the server is in a region close to the end user, it should not be noticeable in a non-faulty flow. (I think I had a small delay functionality in the JS code itself too that could be removed/reduced as well)

waelmas commented 7 months ago

Question though: What type of MFA do you have enabled at the moment? And is it always required or it only asks for MFA sometimes?

Trying to replicate the above scenario on my end but I can't get it to behave the same way.

par-retest commented 7 months ago

thanks for your explanation, the flow makes a lot of sense.

The test account uses a google authenticator app - I also tried without MFA, and it does the same thing. Everything worked 2 weeks ago, so this is a bit weird. Maybe there were some changes on Microsoft's end, like it doesn't redirect you to the /kmsi endpoint after the whole flow? The quickfix of using /login/common works, but it would be nice to get to the bottom of this :D

waelmas commented 7 months ago

It's really weird cause I'm testing 2 accounts on my end (~3 days ago), one with Microsoft authenticator and another without MFA and both end up at the kmsi page. Will dig deeper into it over the week to see if I can replicate it.

Have you tried a guest Chrome profile just to be sure there is no chance any existing cookies are interfering with the flow? And is the account a normal enterprise account?

par-retest commented 7 months ago

I just destroyed my VM and recreated everything from scratch, and this still happens, both with an account without MFA and an account using the android authenticator. I am using guest chrome, and the account is indeed a normal enterprise account, so I am a bit at loss - tell me if you need any debug info from my flow, maybe this could help?

waelmas commented 7 months ago

Could you please share with me (through LinkedIn/Twitter) the email used for testing? It seems like whatever email you are using is causing a redirect to a different flow (I saw this recently with the original blank screen issue and someone shared with me an email to recreate the issue).

Maybe also a list of network requests that are failing if there are any. Also if there are any console logs you see.

One more thing to check, once you get redirected and notice the issue, could you search inside the HTML for "win-scroll" and see if there is an element with that class present on the page?

It's a puzzling issue tbh cause I truly could not reproduce it on my end.

par-retest commented 7 months ago

Unfortunately I can't really share any account, but I think the problem was quite simple, I just didn't think about it because I don't manage my organization 🤦‍♂️. But it is possible to disable "keep me signed in" for an organization (https://learn.microsoft.com/en-us/entra/fundamentals/how-to-manage-stay-signed-in-prompt), which is what my organization did without me knowing. I asked to enable it again, and everything was working as it should!

It's not super easy for me to test things out because I don't manage my organization, so it'll probably be easier for you to test things around. Since one (the flow without KMSI) is a subset of the other (the flow with KMSI) I'm not sure how we would go about handling that though - how would you know that the /login/common page is the latest page? Waiting for KMSI does bring value in form of an extra cookie, right?

waelmas commented 7 months ago

Ah! Haven't thought of that possibility at all! Good catch!

I'll keep this issue open till I implement a fix. I have some theoretical ideas like checking for the presence of specific elements, but will need to setup both flows and see what exactly changes and what could be "the tell" in each scenario.

Will need to spend some time on it over the coming days.

waelmas commented 7 months ago

I've been playing around, but the feature of turning off the stay signed in screen is not available at my test org.

I might have a solution for the variation of end flows, which if also works in the case of the flow stopping at /login/common like you described, it might give us a way more reliable approach to let evilginx fully control when the flow is deemed complete.

Simply edit the lure redirect_url to the /kmsi page, which in theory should force redirect the user upon the capture of the tokens to the /kmsi page which is right now set as the end signal for Frameless BITB.

lures edit 0 redirect_url https://login.fake.com/kmsi

(replace subdomain/domain with the ones from the lure itself)

In theory this should signal the end of the flow and show the interactive calendly page.