Demo Labs - Carnivore: Microsoft External Attack Tool
CC Attribution 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Nevin, Chris
Carnivore is a username enumeration and password spraying tool for Microsoft services (Skype for Business, ADFS, RDWeb, Exchange and Office 365). It originally began as an on-premises Skype for Business enumeration/spray tool as I was finding that these days, organizations often seem to have locked down their implementations of Exchange, however, Skype for Business has been left externally accessible, and has not received as much attention from previous penetration tests due to the lack of tools as impactful as Mailsniper. Overtime this was improved and built upon to bring the same service discovery, username enumeration and password spraying capability to Skype, ADFS, RDWeb, Exchange, and O365 all in the same tool. Carnivore includes new post compromise functionality for Skype for Business (pulling the internal address list and user presence through the API), and smart detection of the username format for all services. As a practical means of entry into an organisation – numerous external penetration tests have uncovered an on-premises Skype for Business or ADFS server even for organisations that have moved Mail/SSO/etc to the cloud.
 Hello, my name is Chris Nevin and I work for NCC Group. So this tool is called Carnivore. So that's a Microsoft external attack tool or assessment tool. So the cryptozoologists amongst you might know this, so that spells meet. So that's very amusing. And it's basically a tool to help pentesters find misconfigurations and vulnerabilities in Microsoft on-premises servers. So also apologies if I talk quickly, but there is quite a lot to get through. So the basic outline of the presentation. So I'm going to start with a demonstration just to show what the tool can do and then dive a bit deeper into some of the techniques and the research behind them after that. So now intro demonstration. Okay, so first a quick overview just to give you a taste of what the tool can do. So just before I kick it off, we've selected all services and we're also going to attempt to discover the internal domain information. You might notice that it's a.nev domain. Obviously that wouldn't normally be a top level domain, but this is my training lab. So first of all, it's going to look for DNS, sorry, do DNS lookups for subdomains which are normally connected with a particular service. So for example, link discover with Skype, then it verifies there's something there. So it's not just a wildcard resolution. And then it also does some checks to make sure is does it also actually seem to be an exchange or a Skype server. So I've also built in some kind of bailout options. So for example, if we get back a server header saying that it's njinks, it's not even windows, we don't need to test every possible endpoint just in case one of them is a Skype server. So yes, so that's something that we do. So it also validates the username enumeration and the password spray URL separately. I'll come on to that in a little bit. But basically there are occasions where an organization might have hidden most things, but there'll be one password spray URL kind of hidden away. So we try the most obvious and then if they don't hit, there are other kind of password spray endpoints that are possible. So yes, hopefully if an organization has something exposed, then we'll be able to find it to report to them. So we also log everything here and you've got export options. If you want to kind of manually export things for some reason, I'll cover Office 365 more at the end. But for this section, if Office 365 is ticked, then it will explicitly check if this has any kind of cloud presence. Even if it's not ticked, then the response to Skype for Business, for example, might come back and say, I'm hosted in the cloud and then we'll still do the standard kind of checks for is it federated and that kind of thing. And then it will add. So say we just did Skype for Business. It says it's in the cloud. It turns out it's federated. We'll get an Office 365 and an ADFS option here. So, okay, so we've also got global verbosity here. So you can kind of tweak that up and down depending on what you want to see. Okay, so let me kick this off. Okay, so the other thing with this Discover internal domain, then it does the fairly standard blank type one until message. And you can see it's pulled back the internal domain name. So at the moment it does that individually for each of these services. And that's because, you know, Skype might be hosted in Germany and ADFS server, the ADFS server might be in Canada for some reason. And so when you're hitting when you're spraying that server, then you've got the internal domain information for the particular server that you're hitting. And in fact, even on a job just last week, then these were all different. So it does happen quite frequently. I might add some kind of advanced options. So you can say just assume they're all the same. But like I say, that's maybe, you know, a recipe for potential disaster. So, okay, we've also got the IP addresses here. So you can obviously check those against your scope. And if you want to, you can kind of run this once, check the IP addresses against your scope, and then do the more active kind of blank until I'm one message. And so for the other thing to mention is for Skype. So link discover is the kind of auto discover service. And that actually points to the real server, which is what we want to hit. So that's why there's two kind of entries for Skype there. So we've now got Skype exchange, ADFS and RD web. So I'm going to show you a quick run through of username enumeration and password spraying, just to give you an idea. So smart enumeration, we'll leave it on the defaults. And we're also going for password one, just kind of standard. So you see there's quite a lot of usernames to try here as it's going through. We found one of a particular format. So it's now continuing to loop through nine different formats. And you'll see that when we discover the correct format, then this will drop drastically because then we switched to just using usernames of that format. So we've now got two of the same format. So first initial surname. And now we've got three. So you'll see that it's now selected that format of J Smith. So everything we do, oh, sorry. We left that continuing, it would just be, as you can see here, it's now less usernames and it's just doing usernames of that format. So now I'll quickly show you password spray as well. And so I'll use that same format J Smith. So for the password spray, that will now spray that in the kind of modern style username format. So we're at navtech.nev and we'll just try summer 2020. Just to see if there happens to be a user who might have been daft enough to use that as a password. So that's going to take a second. I'm sure we're not going to find anyone because of course no one ever uses passwords like this. Who would possibly be that foolish. So here we go. If we give it another couple of seconds, you can see again, this is just doing that one username list. So obviously that's the same number of users total that it will be spraying as the smart enumeration was looking at. Search will be around about now. So there you go. So we've now uncovered one user with that password. We've used the RD web service, but obviously we could have sprayed that on any of these other services. And at the moment, looking at the internal domain information, we can probably assume that they're kind of going to be the same across all of them. Okay, so let's have a look. Let's just do one with Skype. So we should go for. So actually, so just to show you can also password spray enumerated users. So let's use that same. Okay, just 20, 19. Okay, so for that option, then we were spraying the users in the legacy format because those are the ones who've already enumerated. And for username enumeration, that's incredibly slow because for every invalid user, you might have to wait something like 20 or 30 seconds. When we're spraying this list of already enumerated users, and we kind of know already that they exist and actually that's still quite fast, even when spraying in legacy format, because you're not having to wait for every invalid user. So obviously we've now got him as well. You can see we've got this access token here. So I'll quickly show you the address book. So we'll choose this user who we've already got the access token for. Again, I'll explain in more detail some of these other settings. But for now, we're just going to let this go. See what happens. I'm also going to come back to the meeting snooper later. So this is just to kind of show the address book functionality. Here we go. And so you can see now all of these other users popping up. So we get the sick username, the email address, title, department. We can kind of tick these on and off the default settings I've got here are basically the ones we can get relatively quickly. So if I actually expand that and choose to pull some of this other information, it can take quite a long time, especially with quite a large domain. And so in this instance, we just go for the default. It's fairly quick. Obviously for my test lab, this is quite a small number of users, but there you go. You can see the general gist of what's possible with this tool. Okay, so now for some just general statistics. So first of all, I basically ran a version of this against the Alexa, well, the top 100,000 of the Alexa top a million of those 11.79% were attackable at all. And so this shows that of that 11% about 11%. So how many had each service. So obviously some could have had more than one service. This started carnivore started initially as a Skype attacking or assessment tool. So that's secretly my favorite, but you can see it's kind of still getting beaten out by exchange and ADFS, maybe not by all that much. So one caveat with the kind of cloud element here is that there are some false positives in there. And because for this assessment, I didn't explicitly check which whether they were hosted in Office 365. So this is just listing if when I made a link discover request, did it come back and say it was hosted in the cloud. So actually that number might even be higher if we have explicitly asked. And for some of them, it kind of seems to suggest that they're hosted in the cloud, but then maybe everything isn't properly configured and that services and there. It's like say the cloud kind of maybe take with a pinch of salt, but the others, that's what was found and what was kind of verified as existing. So the first part sub domain enumeration, we'll go into that in a little bit more detail. Okay, so as I said before, I split the username enumeration URL and the pass spray or the endpoint validation. Previously it bailed if the username enumeration wasn't there, but then I found multiple times. And in fact on that wider kind of mass assessment I did, then quite often you would find an organization to have just one or just the other. And so for example, here you can see actually there's 53% had a password spray endpoint over 47% with a username enumeration. So kind of 6% more had a password spray endpoint than had both. There were some that just had username enumeration. And what's interesting about this is that it means that for those organizations with just a kind of weird password spray and tele authentication endpoint somewhere, then it seems likely that they potentially might not even be aware of that because they've kind of filed off or hidden away all of the well known. The username enumeration, the standard login points, but then, you know, they have this one password spray endpoint that kind of seems to have alluded that. So yeah, that's kind of interesting. So kind of all looks for some domains in the order shown here. So the statistics are taken from that 11% of the 100,000. So hopefully it means that we'll do as few requests as possible, because obviously we're looking at the one that's highly likely to exist. And then only looking at the others if it doesn't. And so in future I might add an option for a kind of, you know, you can choose between light or full enumeration. So maybe you could choose to just look at the top two and then discount it. And yes, so then again, maybe managing to kind of cut that down even more as to how many requests you need to send. So now username enumeration and a little bit more detail. So we're going to start with the demonstration. Okay, so we've got various options here that I'm going to go through. So firstly, smart enumeration we saw before. So basically that will take these nine different formats of username taken from the top statistically likely usernames lists. And it would it will basically try the top username in each list and then the top of the next list, top of the next list. And essentially as you saw before, it's looking for three valid usernames of the same format. So that's using the timing based difference, which is fairly well known for Skype and exchange. I've added it here for ADFS and RD Web as well. So we've got this advanced option here as well that if you want, you can kind of pick a format and where you want to start in that list. Or you can leave it as it is. You can also do an individual username or you can provide your own list. And all those these pre built ones. So these are kind of standard and service accounts and Council killer was created by my colleague, Owen Bellis. So that's kind of a list of maybe fairly standard user accounts that might be in there. So you can set the password. So obviously also it works on the timing based difference and then also if you get the password right then great. So again, I will just show you obviously this is fairly similar to what we saw before. And one interesting additional point to note is additional information you can get depending on the service. So for Skype, then we can actually determine quite a bit of additional information. So SIP enabled basically just means. So actually, sorry, some of these will only come up if you get the password right as well. So SIP enabled would mean you've got the username of the password right and that user is basically set up on Skype. So account disabled, whatever password you give, you would get that if the account is disabled. You should see that in a second. Switched over. In fact, I might have re enabled that user. So basically if you get a disabled account, then essentially we won't do anything else with it because basically whatever you put in, you're not going to be able to kind of do anything. And for Skype, you can also tell if the password is expired and it's possible that you might actually then be able to take that password. And if you found an endpoint, you know, maybe for the VPN, it might be you can even kind of put that password in and it will ask you to reset it. Obviously on a test, that's probably a little bit too crazy of a thing to do, maybe for a red team or with the kind of technical point of contact, you know, green light. And then for Skype, we can also get this server error. But again, that means you've got the password right. And as I said before, you'll get the access token there if you do. And so yeah, username and emeration. Okay, so as you've just seen, smart enumeration will take nine lists of statistically likely usernames. And it will go through those until it finds three of the same and then automatically select that format and then carry on. Now one interesting thing is this difference between legacy and modern format. So legacy is domain slash username. Modern kind of email style is username at domain. So that can match that they can match, but they don't necessarily have to. And again, the modern format could match the email but doesn't necessarily have to. Now for username enumeration, we can only use the legacy format. And that's to get that timing based difference. And so one interesting thing is that that causes a little hiccup when rolling over to password spraying. So previously I used username enumeration to discover the format and then just assume that it will be the same for the modern format for when we spray. Now because technically that might not be the case, I don't do that anymore. The problem is it means on password spraying, if you choose to use the discovered username format, then invalid usernames will still take ages to do. So what I would suggest is a way of doing this because basically, yes, so username enumeration, every invalid user 30 to 40 seconds. So if you waited for that to finish anyway, that's going to take the rest of the day, a couple of days. So ideally what you want to do anyway is use username enumeration to get the potential, the likely format. That might take five minutes, say, then pause that, switch over to password spray. And then instead of using the discovered format, which because we've only discovered that in the legacy style, then that will take a long time. So instead pick the same format and password spray those. Hopefully you should get some credentials or some invalid, sorry, disabled accounts, which give you a point of that is the correct format. But if you don't, then it is possible that the formats don't match. And you might need to do a little bit more kind of manual going through different potential formats to discover which it is. So the other thing to say is that, so obviously with username enumeration, we discover a valid username, even if the password is wrong, where as the password spraying, we only find out anything if we get both correct. So you can, if you want to stay with username enumeration, you get a nice list and it takes 48 hours. However, because you will essentially be hitting the same users with the password that you're trying, then actually in terms of progressing the test, then you're not going to really lose anything by switching over to passwords spraying. You're going to be hitting the same users. So you're going to find the same users that might have password one as their password, just it will take 10 minutes instead of two days. So yeah, so that would be my suggested method. So now I'm going to show where we get the time based difference and some other things for ADFS and RD web, because I don't think there's much publicly written about those, whereas there is for Skype and Exchange. So this is maybe more interesting. So this is where we get the time based difference for ADFS. Now for ADFS, there's this extra kind of interesting extra bit, which is that it needs an MSIS SAML cookie to be sent in the request. So basically, in order to get that, I first send a request here, sorry, to the same place, but with this single sign out parameter. And basically the response to that will give us the cookie that we need, which we then here include when we make a password guess, as you can see. And then here you'll see the invalid response. So it's just 200 OK. And, you know, so that's told us nothing or with the timing difference, maybe it's told us if the user is valid. And this is a valid response. We get the 302 redirect and it sets this MSIS auth cookie. So for RD web, we make a post request like this. So there's the username and the password to this URL. And if it's invalid, then we get the 200 OK again. And for TSWA auth HTTP only cookie, then that either isn't there or it's blank. So again, we can use timing based difference with the username. Or if it's completely valid, so the username and password are correct. Again, it's the 302 redirect and that TSWA auth HTTP only cookie now has a value as shown there. So now password spraying. So as I said before, there's a little hiccup here with the discovered format. So obviously that's up to you if you want to stick with that discovered format or just simply choose it from the list and we'll spray that in the user at domain style instead. So for password spraying, it basically defaults to using that style if possible because it's quicker. And, you know, also if you provide a list of usernames, you can if you want provide it with domain slash user or user domain and it will use what you've given. So let me have a look. Yep. So also, as I said, you can use these pre built lists. If you want to go for that or you can give it a file of your own. And as I've said, if you want to, you can kind of pre add whatever you want in there and it will use that instead. So another thing to say is that if you want to, you can just go straight to password spraying. You don't have to do the username and emeration first. So yeah, basically if you've done the sub domain and emeration, you've got the internal domain information, you can just go straight here. Maybe you've done some most and you have an idea what the format might be. You can just go straight here and spray it. Okay, so now a little demonstration of password spraying. So I can show you that in a bit more detail as well. Okay, so as you can see here, the top option is use discovered username format. So if we'd already done the username and emeration, then we'd be able to basically just tip that here. And as I've said, that will spray in the legacy format. So you need to be careful. The other choice you've got is that you can just pick what list you want to spray. Again, you can spray these kind of inbuilt lists. You can give it a file of your own. And or you can also spray just enumerated users, which again, we'll use the username that we've already discovered the format that we've already discovered that user in because obviously we know that exists. So again, you can put the password in here. That's obviously distinct to the username and emeration password. And then if I click spray, you'll see that this is much quicker. Because this is able to be multi-threaded, you're not waiting to check that the kind of time based, you know, information is accurate, which multi-threading the username and emeration can kind of throw that off because you're making it do multiple ones at the same time. And as you can see, so it's gone through the list. And as we saw before, it's found this user and access token here. And we've also got one with the disabled account. Okay, so as you saw there, we've got these different columns. So for Office 365 spraying, I'll come on to how we do that at the end. But basically, if you if you if we can spray the Microsoft login portal, then we can determine a valid user versus an invalid user and valid credentials versus invalid credentials. And we can also actually tell if the if you've got the right username and password, but the organization has MFA enabled. So SIP enabled just means they have Skype access. And then depending on the service, we can tell some additional things. So again, Skype is actually my favorite service to look at, because you can actually tell the most from from Skype. So we can tell if the accounts disabled, you can tell if they're SIP enabled. And you can tell if even if the password is expired, so you've got password right, but it's expired. And also this server error, we can still tell that that's a valid username and password. And for exchange and RD web, then we can also still tell if the password is expired, or if it's correct, but not some of the additional information. So username enumeration is timing based. So I only have one location for each of those where that's possible. But for password spraying, there's multiple places we can kind of spray. So again, from the 100,000 that I looked at, that's where the statistics have come from. So this is the order in the sub domain enumeration and when we're validating if the password spray endpoints there, this is the order that kind of all the look for those in. Again, hopefully this will reduce how many requests we need to make. And in the future, again, maybe that advanced option to say just look at the top two. Obviously, you can see here, the top two would actually get the vast majority of in, you know, would have found it in the vast majority of cases. And then we've got somewhere is literally just one out of that 11% that had slash web ticket was there. And so this is a mix of known endpoints kind of publicly written about ones taken from IS from the server itself and which allow until I'm authentication. So until I'm authentication going to go into a bit more detail now. So, yes, so just to mention briefly, when I had a look there kind of doesn't seem to be that much for until I'm web based until I'm authentication spraying, it's possible hydro or something similar might do it, but they didn't seem to be that many tools for it. So here's a little bit of code. Very simple for C sharp. So we can literally just create the new network credential, give it the username and password. And then in the response, if it's 401 unauthorized, it's bad. Otherwise, you're good to go. So yeah, incredibly simple and carnivore is able to password spray until I'm off endpoints. And so for those you can still do the blank type one message. But actually, it's part of the protocol is kind of determining and including the domain name. So here when we're giving the username and password, we can literally just say see Scott password one. And actually, as part of this request, it will add the nevtech element of that. So an interesting thing to note is that, as I said before, when I included some entombed authentication endpoints with the list of sub domains that I look at, then there were some quite big organizations where everything else seemed to not be accessible. And then you've got one kind of weird until I'm off endpoint hidden away. Meaning that they're still susceptible to password spraying against the internal domain. Essentially, I mean, this could even be used for denial of service, because yes, we hit the normal password lockout policies. But essentially, if you purposefully hit that, and you know, you've locked out everyone in the domain. So that's obviously something that an organization would want to be aware of. Because that would be a bad day for them as well. So quick sidetrack into a note on some of these different services, just in case you haven't seen them before. And so ADFS, it's a portable that can be present to allow you to sign into different third party services. Sometimes these might be assumed to be internal. So on past red teams, then this has given access to full job posting applications. So third party applications, but they were linked to the company's Twitter and LinkedIn, all of their job postings. So obviously, for kind of phishing or ongoing attacks, then having access through ADFS to that company's kind of LinkedIn job postings, or even reputational damage could have been fairly troubling. So basically, you go to the same URL that I gave earlier, and that would give or would normally give a kind of drop down list where you'll see the different applications that you can authenticate into. So I've also seen internal service desks that you can get into was logging all call center queries. So that contained incredibly sensitive customer details and information, because it was everyone in their call center, putting it putting in, you know, this customer with this bank account number and this credit card number has this question. And that was basically accessible externally through ADFS and also things like HR user admin portals. And so one other thing to note there is the if it's Office 365 and federated equals win. So basically, Office 365 is password spraying avoidance and defense mechanisms are fairly brutal. But basically, if the organization is federated, it means that you not not just that you can but that you have to hit the ADFS server. And the response to a request I'll show in a bit will tell you where that ADFS server is and basically, yeah, so if that exists, it's actually a lot better for us, because it means we can avoid Office 365's robust defense mechanisms. So we're just hitting ADFS the same as we would before. And for our DP, that one's fairly simple. It's literally just remote desktop through the web. Depending on how that's configured, maybe you'll be able to RDP into a workstation and domain, you know, things like that. And yes, so hopefully you'll have seen Skype and Outlook before. Now post compromise, we're going to look at the address list pulling first with a quick demonstration. Okay, so just as a reminder, so this is used to pull the address book through the UCWA API, just to remind you what that looked like. So we had these options here. So if you untick both of those, that means you're just looking for the compromised user. So the personal contacts is the personal contacts of that compromised user. So their favorites. That's an interesting one for say ongoing social engineering, because then you know, and from the other information you've got here, then you know, okay, my compromised user has this job. My favorites include these people and they have these jobs. So in terms of kind of a fashioning of good fishing payload, then obviously that would be incredibly useful. We can kind of run this on the personal contacts first and then add in the full address list. Just to make that distinction or yes, just pick the full address list. The data here, as I said before, so the ones that are chosen by default, those are the ones that are quicker to get. So for some reason, the way that the UCWA API works, then we get different pieces of information depending on where we've queried that person. So if they're you, you get this information. If they are personal contacts, you get this information. If it's through the people search function, you get that information. So this is kind of the stripped down list of what you get in every case. Then if you want to kind of go on and pull everything back, we can. But that can take numerous additional requests per user. So obviously for a domain of say 6,000 people, that could take an incredibly long amount of time. So what we do is if we kick this off, and I've just missed the button, that's good, good sign. So you'll see it will pull back the kind of standard information for the users first, and then it will kick off some additional threads to pull that additional information. And then as we go, you'll see that start to fill in. And then I'll go over some of these things later and the additional settings here. I'll go over in more detail. Okay, so as you just saw, the information that we can get back through Skype for Business is a bit of a social engineers dream. So you've got the department, you've got the office location they work in, you've got even whether they're online or offline. Additionally, this does say online mobile online desktop. So I've never fully seen that work in a useful way, but that options there. You can also get email address phone number. And this note here is any status message that they've set. So those quite frequently I've seen people will put on there about annual leave if they're going to be out of the office. So obviously again, as far as social engineering goes, you know what office they're in, you know, the name, email address, what their job title is, you know, they're going to be out of the office. So there's a lot of information for maybe even being able to turn up and say, you know, I'm supposed to be meeting so and so or, or even impersonating someone and you know they're definitely not going to be in the office. So so I was saying the problem is some of this extra information does take a large number of additional requests. So so yeah, by all means tick all, but just beware that might take a very long time. And yeah, those are the options you've got. So carnivore pulls the internal dress book back using people search on the UC with the UC WA API. So this does mean that we're essentially having to search letter by letter a through Z. However, there's an upper limit of 100 on the amount of responses it returns. And there isn't a next link that we can say is the first 100 now go to the next link for the next, you know, however many and so on. So basically what we have to resort to is searching by digraphs and try graphs. So essentially a B a C a D and then even a B C a B D a B E. And so basically we can then take either the from the top statistically likely usernames list, we can do all of the likely and unique kind of three letters that are there, or you can do all possible to character combinations. So what's interesting and fun about the UC WA API is that there doesn't seem to be much rhyme or reason as to the way that works in terms of what we get back. So to take an example, if we're looking for every pool in the domain so we know there's four, and we search for P, you get back 150 results. So we're just going to get the top 100. There's two polls in there. So then we search for PA, we get back 20 results. But this time there's three pools. So we've got one extra. But for some reason, even though we haven't hit the upper limit, we've still not actually got back every pool who's in the domain. So then we search for PA you. And now we get this mysterious rogue fourth pool that we've never seen before. So essentially, in the interest of me keeping my sanity, I've stuck with diagrams and try graphs. It's possible you might want to go on and do quad graphs and quink graphs and whatever else they're called. However, so when I looked at this with the common try graphs, then and then with every possible three character combination that actually only added an additional I think it was maybe even one user in a domain of 6000. And the difference is common does 2249 requests, whereas every possible was about 17 and a half thousand. So all of that for one additional user that as I've said was kind of hiding away. And we weren't able to get otherwise. So essentially, hopefully that explains the kind of options on the address list a little bit more. One additional kind of side note. So it's fairly uncommon, but I've seen it where a misconfigured Microsoft Web App proxy basically meant that when you off to the first server, and it gives you back the token and then you try and use that against the applications end point. And then it's essentially sends it to the wrong place or you've been off to the wrong box. And so it then doesn't like it. That actually also stopped the legitimate Skype client from being able to authenticate, you know, to Skype. However, now carnival is able to detect that it reoffs to the correct box and carries on. So basically carnival is able to connect and carry on using the API, even when the legitimate client actually couldn't. Okay, so now the final post compromise function, which is meeting snooper. And so unfortunately my lab servers stopped working for this. So we have to make do with screenshots. Okay, so as you can see here, this is the meeting snooper tab. So once you've compromised the user, if you've got Skype available. So this uses the UCWA API as well. And then you can go here and you have to choose. You have to pick the compromised user that you want to use there. So now we can either choose basically we can do this for all compromised users or just a selected user. Now one thing to say is that this only picks up currently scheduled meetings. Obviously, so basically we can run this throughout the day multiple times or you know at the start of the day you could run it see if any new meetings have been added and then kind of keep running it to pull back new information. So first of all, it dumps the standard dial in information to the output log. So if you've ever had an email inviting you to a Skype meeting, this will look fairly familiar to you. So you've got the internal number you can dial and then a number for each country or city within that country. And so now apologies for how utterly rubbish this looks. As I said, my training lab unfortunately kind of packing in at the key moment there. But yeah, so just stress this isn't an exploit or a zero day. It's basically highlighting what's already possible through kind of weaponization of the UCWA API for attackers. Obviously it does depend on compromised credentials. But basically, so far this tool has shown how we can go from external over the internet to kind of complete compromise and to this point, being able to dump out scheduled meetings for compromised users. So one thing to say is that when kind of using this tool on on jobs, then often you find if you're going to get anyone, you probably are going to get like 50 to 100 users. And obviously, in that case, then this becomes more interesting, because you know one user might have one meeting that week. But if you've got 50 users, then maybe you've got someone who's a little bit more interesting. So you can then see here, what happens when you run this tool is that it gives you information for each meeting that compromised user has scheduled. So the conference ID there is the pin. So basically when you dial in, you dial into the phone number and ask you for a pin, and that's that conference ID. And basically that conference ID is unique to that user. So when you dial in, you'll be impersonating whoever it is that you've compromised. So for example, this you dial in, you put the pin and then you show up as being, say Chris Nevin guest. Now, obviously, if the people in the meeting are kind of using the desktop application, then maybe it would look weird to have multiple Chris Nevin guests. If everyone's using the phone to dial in, I'm not sure that they would know this is a tool at all. And in fact, even if they did see these two Chris Nevin guests, you know, how likely is it that people are going to assume, oh, this is someone impersonating and joining in and listening, as opposed to, you know, maybe there's some weird bug that's happening. So the information we get here includes the subject of the meeting and the attendees. So obviously these meetings here I've scheduled just to kind of demonstrate. But obviously this could be a lot more juicy. So for example, you've compromised the user, you know, from their address book, they're the head of financial fraud. And this meeting subject shows it's the weekly financial crime investigation update. So obviously you can see why this would be kind of concerning for an organization if this was possible. And because, again, without any exploit, any need for any further phishing or payloads being executed, you've basically gone from being over the internet to being able to listen in on and even record the sensitive meetings essentially impersonating that user. And so on the right you can see the lobby bypass enabled. That basically means that if you dial in does it bypass the lobby. If that's enabled that means you're not even in a waiting room that someone has to let you in. So the join URL. If you go to that, you can join the meeting and you can basically enter a name of your choice. So obviously one thing you could do is again, you've done the address book. And, you know, is there a social engineering angle, maybe you could kind of choose your name based on that, potentially might be more likely to get caught, whereas actually just dialing in and there being two of the compromised user is maybe less trouble in. So the another thing to say is that the API basically only seems to give the meeting expiry. So that's two weeks after the meeting ends. So carnival will take off, it will remove the two weeks for you automatically. And then it's kind of maybe you'll need to do some kind of common sense around that. So for example, you see the top meeting there. We actually have been able to pull is that the meeting ends at 1130. Now I've set the subject for that one to be the time while I was troubleshooting. So you can see that actually that meeting starts at 11. As I say, normally you wouldn't get that information, because that's the subject. So obviously, yeah, if you apply some common sense to it, then you can see, OK, the meeting ends at 1130, it probably starts at 11 or even 1030. So yeah, so that's the meeting snooping, what you get back from it, basically. So there are a couple of extra points to mention, which are that this only seems to be able to pull back self scheduled meetings. So again, doesn't fully make sense to me because obviously in outlook or something, you don't just see meetings you've scheduled, you see every meeting that you're scheduled to be a part of. Unfortunately, we're not able to get that through this tool. So yeah, and then also meeting and time only, as I said before. Now there are some weird edge cases with that. So for example, I set a recurring meeting. So the only information we get back is that it ends on the 26th of December 2022, which obviously isn't that useful. Again, maybe you could figure out, OK, that's a Friday, it's a half 10. So maybe it's every Friday. But again, we can't get that back through the API, unfortunately. Okay, so Office 365. So I'm not going to demo this. So what I've been showing so far is basically just my lab. And so yeah, we're not going to demo Office 365, but I'm going to talk you through how Carnival works. So for example, sorry, one thing to say is that username enumeration that doesn't require a password guest has been quite widely covered. So there's things like 0365 or 0365 enum. So I'm just going to quickly kind of get into password spraying and give some key pointers. So as I said before, federated as a win. So just the usual active directory rules will apply to lockouts. But again, that kind of doesn't include the extremely robust Office 365 rules. So as I've said, there's a link that I'm about to show you where you can find out if an organization is federated or not. If it is, you'll get back the ADFS server location and Carnival will add that automatically. So if it's not federated, we can still spray, sorry, we have to spray the Office portal, but then we can also determine if a user and password is valid, even if we have MFA on there. And sorry, I should have said again, with federated, if it's federated, you have to spray ADFS and you can't spray the Office portal. You won't get back anything interesting, anything useful. So password spray countermeasures for Office 365. So they have things like trusted versus untrusted network have separate bad password counts. So again, if you're from the untrusted side, which presumably you would be from an untrusted network, then, you know, your password spray is adding to account of everyone else in the world. So again, lockout is fairly frequent and quick. But from Microsoft side, obviously that's designed so that then the genuine user can still sign in while on their corporate VPN or something like that. So obviously good security measures but difficult from a red team perspective. So first of all, to find out if the organization is federated. So this is an example request here. So the username itself is relevant. It's just the domain.com that we're looking for. And the response here. So if they were federated, that would say federated instead of managed. And it can also include some kind of boilerplate text. So for example, is keep me signed in disabled. Obviously that one might be interesting from a red team perspective because maybe it hints that they have fairly good security and they've had the configuration looked at because users can't just stay signed in forever. You also get the Federation brand name there and you can get back, you know, logo information and that kind of thing. And so also if this said federated, then we would see the location of the ADFS authentication endpoint there as well. So for password spraying, this is how Carnivore does it. So this is the endpoint that we're hitting. There's the username and the password. So the client ID and the scope, obviously that could be tweaked to maybe be a little bit more realistic or representative. But this is what Carnivore uses. And so this first one is if there's an invalid password. Now obviously the actual response here says invalid username or password. So obviously that seems like maybe that's going to be a bit tricky for us. Is it the username or is it the password? We're not fully sure. But then if the username is incorrect, then we get this message back. The user account does not exist in that directory. So obviously from that we can tell the previous response means the password's wrong, not the username. And just to also mention there where it says email hidden, I've not added that. That's the actual response. So then this is a valid user and password without NFA. So again, this is specific to the request that I make in Carnivore. So because we gave a client ID that doesn't exist, then if the username and password is correct, you'd get this unauthorized client and a message that that application doesn't exist. Because obviously it's not a proper client ID. And again, so if it's valid user and password with MFA, then again we get this invalid grant. But now it's telling us that it's due to configuration meaning that you need to supply multi-factor authentication. So again, username and password is correct, but you need MFA. So outro very briefly. Yes, so almost forgot to put it in, but here's a link to the tool itself. So obviously you can go there and download the latest version and any issues or anything that you want to bring up there. I'll be happy to try and help wherever I can. So thank you for listening. Hopefully it's been useful and they enjoy carnivoring.
 Hello, my name is Chris Nevin and I work for NCC Group.  So this tool is called Carnivore.  So that's a Microsoft external attack tool or assessment tool.  So the cryptozoologists amongst you might know this, so that spells meet.  So that's very amusing.  And it's basically a tool to help pentesters find misconfigurations and vulnerabilities in Microsoft on-premises servers.  So also apologies if I talk quickly, but there is quite a lot to get through.  So the basic outline of the presentation.  So I'm going to start with a demonstration just to show what the tool can do and then dive a bit deeper into some of the techniques and the research behind them after that.  So now intro demonstration.  Okay, so first a quick overview just to give you a taste of what the tool can do.  So just before I kick it off, we've selected all services and we're also going to attempt to discover the internal domain information.  You might notice that it's a.nev domain.  Obviously that wouldn't normally be a top level domain, but this is my training lab.  So first of all, it's going to look for DNS, sorry, do DNS lookups for subdomains which are normally connected with a particular service.  So for example, link discover with Skype, then it verifies there's something there.  So it's not just a wildcard resolution.  And then it also does some checks to make sure is does it also actually seem to be an exchange or a Skype server.  So I've also built in some kind of bailout options.  So for example, if we get back a server header saying that it's njinks, it's not even windows, we don't need to test every possible endpoint just in case one of them is a Skype server.  So yes, so that's something that we do.  So it also validates the username enumeration and the password spray URL separately.  I'll come on to that in a little bit.  But basically there are occasions where an organization might have hidden most things, but there'll be one password spray URL kind of hidden away.  So we try the most obvious and then if they don't hit, there are other kind of password spray endpoints that are possible.  So yes, hopefully if an organization has something exposed, then we'll be able to find it to report to them.  So we also log everything here and you've got export options.  If you want to kind of manually export things for some reason, I'll cover Office 365 more at the end.  But for this section, if Office 365 is ticked, then it will explicitly check if this has any kind of cloud presence.  Even if it's not ticked, then the response to Skype for Business, for example, might come back and say, I'm hosted in the cloud and then we'll still do the standard kind of checks for is it federated and that kind of thing.  And then it will add.  So say we just did Skype for Business.  It says it's in the cloud.  It turns out it's federated.  We'll get an Office 365 and an ADFS option here.  So, okay, so we've also got global verbosity here.  So you can kind of tweak that up and down depending on what you want to see.  Okay, so let me kick this off.  Okay, so the other thing with this Discover internal domain, then it does the fairly standard blank type one until message.  And you can see it's pulled back the internal domain name.  So at the moment it does that individually for each of these services.  And that's because, you know, Skype might be hosted in Germany and ADFS server, the ADFS server might be in Canada for some reason.  And so when you're hitting when you're spraying that server, then you've got the internal domain information for the particular server that you're hitting.  And in fact, even on a job just last week, then these were all different.  So it does happen quite frequently.  I might add some kind of advanced options.  So you can say just assume they're all the same.  But like I say, that's maybe, you know, a recipe for potential disaster.  So, okay, we've also got the IP addresses here.  So you can obviously check those against your scope.  And if you want to, you can kind of run this once, check the IP addresses against your scope, and then do the more active kind of blank until I'm one message.  And so for the other thing to mention is for Skype.  So link discover is the kind of auto discover service.  And that actually points to the real server, which is what we want to hit.  So that's why there's two kind of entries for Skype there.  So we've now got Skype exchange, ADFS and RD web.  So I'm going to show you a quick run through of username enumeration and password spraying, just to give you an idea.  So smart enumeration, we'll leave it on the defaults.  And we're also going for password one, just kind of standard.  So you see there's quite a lot of usernames to try here as it's going through.  We found one of a particular format.  So it's now continuing to loop through nine different formats.  And you'll see that when we discover the correct format, then this will drop drastically because then we switched to just using usernames of that format.  So we've now got two of the same format.  So first initial surname.  And now we've got three.  So you'll see that it's now selected that format of J Smith.  So everything we do, oh, sorry.  We left that continuing, it would just be, as you can see here, it's now less usernames and it's just doing usernames of that format.  So now I'll quickly show you password spray as well.  And so I'll use that same format J Smith.  So for the password spray, that will now spray that in the kind of modern style username format.  So we're at navtech.nev and we'll just try summer 2020.  Just to see if there happens to be a user who might have been daft enough to use that as a password.  So that's going to take a second.  I'm sure we're not going to find anyone because of course no one ever uses passwords like this.  Who would possibly be that foolish.  So here we go.  If we give it another couple of seconds, you can see again, this is just doing that one username list.  So obviously that's the same number of users total that it will be spraying as the smart enumeration was looking at.  Search will be around about now.  So there you go.  So we've now uncovered one user with that password.  We've used the RD web service, but obviously we could have sprayed that on any of these other services.  And at the moment, looking at the internal domain information, we can probably assume that they're kind of going to be the same across all of them.  Okay, so let's have a look.  Let's just do one with Skype.  So we should go for.  So actually, so just to show you can also password spray enumerated users.  So let's use that same.  Okay, just 20, 19.  Okay, so for that option, then we were spraying the users in the legacy format because those are the ones who've already enumerated.  And for username enumeration, that's incredibly slow because for every invalid user, you might have to wait something like 20 or 30 seconds.  When we're spraying this list of already enumerated users, and we kind of know already that they exist and actually that's still quite fast, even when spraying in legacy format, because you're not having to wait for every invalid user.  So obviously we've now got him as well.  You can see we've got this access token here.  So I'll quickly show you the address book.  So we'll choose this user who we've already got the access token for.  Again, I'll explain in more detail some of these other settings.  But for now, we're just going to let this go. See what happens.  I'm also going to come back to the meeting snooper later.  So this is just to kind of show the address book functionality.  Here we go.  And so you can see now all of these other users popping up. So we get the sick username, the email address, title, department.  We can kind of tick these on and off the default settings I've got here are basically the ones we can get relatively quickly.  So if I actually expand that and choose to pull some of this other information, it can take quite a long time, especially with quite a large domain.  And so in this instance, we just go for the default. It's fairly quick.  Obviously for my test lab, this is quite a small number of users, but there you go.  You can see the general gist of what's possible with this tool.  Okay, so now for some just general statistics.  So first of all, I basically ran a version of this against the Alexa, well, the top 100,000 of the Alexa top a million of those 11.79% were attackable at all.  And so this shows that of that 11% about 11%.  So how many had each service. So obviously some could have had more than one service.  This started carnivore started initially as a Skype attacking or assessment tool.  So that's secretly my favorite, but you can see it's kind of still getting beaten out by exchange and ADFS, maybe not by all that much.  So one caveat with the kind of cloud element here is that there are some false positives in there.  And because for this assessment, I didn't explicitly check which whether they were hosted in Office 365.  So this is just listing if when I made a link discover request, did it come back and say it was hosted in the cloud.  So actually that number might even be higher if we have explicitly asked.  And for some of them, it kind of seems to suggest that they're hosted in the cloud, but then maybe everything isn't properly configured and that services and there.  It's like say the cloud kind of maybe take with a pinch of salt, but the others, that's what was found and what was kind of verified as existing.  So the first part sub domain enumeration, we'll go into that in a little bit more detail.  Okay, so as I said before, I split the username enumeration URL and the pass spray or the endpoint validation.  Previously it bailed if the username enumeration wasn't there, but then I found multiple times.  And in fact on that wider kind of mass assessment I did, then quite often you would find an organization to have just one or just the other.  And so for example, here you can see actually there's 53% had a password spray endpoint over 47% with a username enumeration.  So kind of 6% more had a password spray endpoint than had both.  There were some that just had username enumeration.  And what's interesting about this is that it means that for those organizations with just a kind of weird password spray and tele authentication endpoint somewhere, then it seems likely that they potentially might not even be aware of that because they've kind of filed off or hidden away all of the well known.  The username enumeration, the standard login points, but then, you know, they have this one password spray endpoint that kind of seems to have alluded that.  So yeah, that's kind of interesting.  So kind of all looks for some domains in the order shown here.  So the statistics are taken from that 11% of the 100,000.  So hopefully it means that we'll do as few requests as possible, because obviously we're looking at the one that's highly likely to exist.  And then only looking at the others if it doesn't.  And so in future I might add an option for a kind of, you know, you can choose between light or full enumeration.  So maybe you could choose to just look at the top two and then discount it.  And yes, so then again, maybe managing to kind of cut that down even more as to how many requests you need to send.  So now username enumeration and a little bit more detail.  So we're going to start with the demonstration.  Okay, so we've got various options here that I'm going to go through.  So firstly, smart enumeration we saw before.  So basically that will take these nine different formats of username taken from the top statistically likely usernames lists.  And it would it will basically try the top username in each list and then the top of the next list, top of the next list.  And essentially as you saw before, it's looking for three valid usernames of the same format.  So that's using the timing based difference, which is fairly well known for Skype and exchange.  I've added it here for ADFS and RD Web as well.  So we've got this advanced option here as well that if you want, you can kind of pick a format and where you want to start in that list.  Or you can leave it as it is.  You can also do an individual username or you can provide your own list.  And all those these pre built ones. So these are kind of standard and service accounts and Council killer was created by my colleague, Owen Bellis.  So that's kind of a list of maybe fairly standard user accounts that might be in there.  So you can set the password.  So obviously also it works on the timing based difference and then also if you get the password right then great.  So again, I will just show you obviously this is fairly similar to what we saw before.  And one interesting additional point to note is additional information you can get depending on the service.  So for Skype, then we can actually determine quite a bit of additional information.  So SIP enabled basically just means.  So actually, sorry, some of these will only come up if you get the password right as well.  So SIP enabled would mean you've got the username of the password right and that user is basically set up on Skype.  So account disabled, whatever password you give, you would get that if the account is disabled.  You should see that in a second.  Switched over.  In fact, I might have re enabled that user.  So basically if you get a disabled account, then essentially we won't do anything else with it because basically whatever you put in, you're not going to be able to kind of do anything.  And for Skype, you can also tell if the password is expired and it's possible that you might actually then be able to take that password.  And if you found an endpoint, you know, maybe for the VPN, it might be you can even kind of put that password in and it will ask you to reset it.  Obviously on a test, that's probably a little bit too crazy of a thing to do, maybe for a red team or with the kind of technical point of contact, you know, green light.  And then for Skype, we can also get this server error.  But again, that means you've got the password right.  And as I said before, you'll get the access token there if you do.  And so yeah, username and emeration.  Okay, so as you've just seen, smart enumeration will take nine lists of statistically likely usernames.  And it will go through those until it finds three of the same and then automatically select that format and then carry on.  Now one interesting thing is this difference between legacy and modern format.  So legacy is domain slash username.  Modern kind of email style is username at domain.  So that can match that they can match, but they don't necessarily have to.  And again, the modern format could match the email but doesn't necessarily have to.  Now for username enumeration, we can only use the legacy format.  And that's to get that timing based difference.  And so one interesting thing is that that causes a little hiccup when rolling over to password spraying.  So previously I used username enumeration to discover the format and then just assume that it will be the same for the modern format for when we spray.  Now because technically that might not be the case, I don't do that anymore.  The problem is it means on password spraying, if you choose to use the discovered username format, then invalid usernames will still take ages to do.  So what I would suggest is a way of doing this because basically, yes, so username enumeration, every invalid user 30 to 40 seconds.  So if you waited for that to finish anyway, that's going to take the rest of the day, a couple of days.  So ideally what you want to do anyway is use username enumeration to get the potential, the likely format.  That might take five minutes, say, then pause that, switch over to password spray.  And then instead of using the discovered format, which because we've only discovered that in the legacy style, then that will take a long time.  So instead pick the same format and password spray those.  Hopefully you should get some credentials or some invalid, sorry, disabled accounts, which give you a point of that is the correct format.  But if you don't, then it is possible that the formats don't match.  And you might need to do a little bit more kind of manual going through different potential formats to discover which it is.  So the other thing to say is that, so obviously with username enumeration, we discover a valid username, even if the password is wrong,  where as the password spraying, we only find out anything if we get both correct.  So you can, if you want to stay with username enumeration, you get a nice list and it takes 48 hours.  However, because you will essentially be hitting the same users with the password that you're trying, then actually in terms of progressing the test,  then you're not going to really lose anything by switching over to passwords spraying.  You're going to be hitting the same users.  So you're going to find the same users that might have password one as their password, just it will take 10 minutes instead of two days.  So yeah, so that would be my suggested method.  So now I'm going to show where we get the time based difference and some other things for ADFS and RD web,  because I don't think there's much publicly written about those, whereas there is for Skype and Exchange.  So this is maybe more interesting.  So this is where we get the time based difference for ADFS.  Now for ADFS, there's this extra kind of interesting extra bit, which is that it needs an MSIS SAML cookie to be sent in the request.  So basically, in order to get that, I first send a request here, sorry, to the same place, but with this single sign out parameter.  And basically the response to that will give us the cookie that we need, which we then here include when we make a password guess, as you can see.  And then here you'll see the invalid response.  So it's just 200 OK.  And, you know, so that's told us nothing or with the timing difference, maybe it's told us if the user is valid.  And this is a valid response.  We get the 302 redirect and it sets this MSIS auth cookie.  So for RD web, we make a post request like this.  So there's the username and the password to this URL.  And if it's invalid, then we get the 200 OK again.  And for TSWA auth HTTP only cookie, then that either isn't there or it's blank.  So again, we can use timing based difference with the username.  Or if it's completely valid, so the username and password are correct.  Again, it's the 302 redirect and that TSWA auth HTTP only cookie now has a value as shown there.  So now password spraying.  So as I said before, there's a little hiccup here with the discovered format.  So obviously that's up to you if you want to stick with that discovered format or just simply choose it from the list and we'll spray that in the user at domain style instead.  So for password spraying, it basically defaults to using that style if possible because it's quicker.  And, you know, also if you provide a list of usernames, you can if you want provide it with domain slash user or user domain and it will use what you've given.  So let me have a look.  Yep. So also, as I said, you can use these pre built lists.  If you want to go for that or you can give it a file of your own.  And as I've said, if you want to, you can kind of pre add whatever you want in there and it will use that instead.  So another thing to say is that if you want to, you can just go straight to password spraying.  You don't have to do the username and emeration first.  So yeah, basically if you've done the sub domain and emeration, you've got the internal domain information, you can just go straight here.  Maybe you've done some most and you have an idea what the format might be.  You can just go straight here and spray it.  Okay, so now a little demonstration of password spraying.  So I can show you that in a bit more detail as well.  Okay, so as you can see here, the top option is use discovered username format.  So if we'd already done the username and emeration, then we'd be able to basically just tip that here.  And as I've said, that will spray in the legacy format.  So you need to be careful.  The other choice you've got is that you can just pick what list you want to spray.  Again, you can spray these kind of inbuilt lists.  You can give it a file of your own.  And or you can also spray just enumerated users, which again, we'll use the username that we've already discovered the format that we've already discovered that user in because obviously we know that exists.  So again, you can put the password in here.  That's obviously distinct to the username and emeration password.  And then if I click spray, you'll see that this is much quicker.  Because this is able to be multi-threaded, you're not waiting to check that the kind of time based, you know, information is accurate, which multi-threading the username and emeration can kind of throw that off because you're making it do multiple ones at the same time.  And as you can see, so it's gone through the list. And as we saw before, it's found this user and access token here. And we've also got one with the disabled account.  Okay, so as you saw there, we've got these different columns.  So for Office 365 spraying, I'll come on to how we do that at the end.  But basically, if you if you if we can spray the Microsoft login portal, then we can determine a valid user versus an invalid user and valid credentials versus invalid credentials.  And we can also actually tell if the if you've got the right username and password, but the organization has MFA enabled.  So SIP enabled just means they have Skype access. And then depending on the service, we can tell some additional things. So again, Skype is actually my favorite service to look at, because you can actually tell the most from from Skype.  So we can tell if the accounts disabled, you can tell if they're SIP enabled. And you can tell if even if the password is expired, so you've got password right, but it's expired.  And also this server error, we can still tell that that's a valid username and password.  And for exchange and RD web, then we can also still tell if the password is expired, or if it's correct, but not some of the additional information.  So username enumeration is timing based. So I only have one location for each of those where that's possible. But for password spraying, there's multiple places we can kind of spray.  So again, from the 100,000 that I looked at, that's where the statistics have come from.  So this is the order in the sub domain enumeration and when we're validating if the password spray endpoints there, this is the order that kind of all the look for those in.  Again, hopefully this will reduce how many requests we need to make. And in the future, again, maybe that advanced option to say just look at the top two.  Obviously, you can see here, the top two would actually get the vast majority of in, you know, would have found it in the vast majority of cases. And then we've got somewhere is literally just one out of that 11% that had slash web ticket was there.  And so this is a mix of known endpoints kind of publicly written about ones taken from IS from the server itself and which allow until I'm authentication. So until I'm authentication going to go into a bit more detail now.  So, yes, so just to mention briefly, when I had a look there kind of doesn't seem to be that much for until I'm web based until I'm authentication spraying, it's possible hydro or something similar might do it, but they didn't seem to be that many tools for it.  So here's a little bit of code. Very simple for C sharp. So we can literally just create the new network credential, give it the username and password. And then in the response, if it's 401 unauthorized, it's bad.  Otherwise, you're good to go.  So yeah, incredibly simple and carnivore is able to password spray until I'm off endpoints. And so for those you can still do the blank type one message.  But actually, it's part of the protocol is kind of determining and including the domain name. So here when we're giving the username and password, we can literally just say see Scott password one. And actually, as part of this request, it will add the nevtech element of that.  So an interesting thing to note is that, as I said before, when I included some entombed authentication endpoints with the list of sub domains that I look at, then there were some quite big organizations where everything else seemed to not be accessible.  And then you've got one kind of weird until I'm off endpoint hidden away. Meaning that they're still susceptible to password spraying against the internal domain.  Essentially, I mean, this could even be used for denial of service, because yes, we hit the normal password lockout policies. But essentially, if you purposefully hit that, and you know, you've locked out everyone in the domain.  So that's obviously something that an organization would want to be aware of. Because that would be a bad day for them as well.  So quick sidetrack into a note on some of these different services, just in case you haven't seen them before. And so ADFS, it's a portable that can be present to allow you to sign into different third party services.  Sometimes these might be assumed to be internal. So on past red teams, then this has given access to full job posting applications.  So third party applications, but they were linked to the company's Twitter and LinkedIn, all of their job postings. So obviously, for kind of phishing or ongoing attacks, then having access through ADFS to that company's kind of LinkedIn job postings,  or even reputational damage could have been fairly troubling. So basically, you go to the same URL that I gave earlier, and that would give or would normally give a kind of drop down list where you'll see the different applications that you can authenticate into.  So I've also seen internal service desks that you can get into was logging all call center queries. So that contained incredibly sensitive customer details and information, because it was everyone in their call center, putting it putting in, you know, this customer with this bank account number and this credit card number has this question.  And that was basically accessible externally through ADFS and also things like HR user admin portals.  And so one other thing to note there is the if it's Office 365 and federated equals win. So basically, Office 365 is password spraying avoidance and defense mechanisms are fairly brutal.  But basically, if the organization is federated, it means that you not not just that you can but that you have to hit the ADFS server.  And the response to a request I'll show in a bit will tell you where that ADFS server is and basically, yeah, so if that exists, it's actually a lot better for us, because it means we can avoid Office 365's robust defense mechanisms.  So we're just hitting ADFS the same as we would before.  And for our DP, that one's fairly simple. It's literally just remote desktop through the web.  Depending on how that's configured, maybe you'll be able to RDP into a workstation and domain, you know, things like that.  And yes, so hopefully you'll have seen Skype and Outlook before.  Now post compromise, we're going to look at the address list pulling first with a quick demonstration.  Okay, so just as a reminder, so this is used to pull the address book through the UCWA API, just to remind you what that looked like.  So we had these options here.  So if you untick both of those, that means you're just looking for the compromised user.  So the personal contacts is the personal contacts of that compromised user. So their favorites.  That's an interesting one for say ongoing social engineering, because then you know, and from the other information you've got here, then you know, okay, my compromised user has this job.  My favorites include these people and they have these jobs. So in terms of kind of a fashioning of good fishing payload, then obviously that would be incredibly useful.  We can kind of run this on the personal contacts first and then add in the full address list.  Just to make that distinction or yes, just pick the full address list.  The data here, as I said before, so the ones that are chosen by default, those are the ones that are quicker to get.  So for some reason, the way that the UCWA API works, then we get different pieces of information depending on where we've queried that person.  So if they're you, you get this information. If they are personal contacts, you get this information.  If it's through the people search function, you get that information. So this is kind of the stripped down list of what you get in every case.  Then if you want to kind of go on and pull everything back, we can. But that can take numerous additional requests per user.  So obviously for a domain of say 6,000 people, that could take an incredibly long amount of time.  So what we do is if we kick this off, and I've just missed the button, that's good, good sign.  So you'll see it will pull back the kind of standard information for the users first, and then it will kick off some additional threads to pull that additional information.  And then as we go, you'll see that start to fill in. And then I'll go over some of these things later and the additional settings here.  I'll go over in more detail.  Okay, so as you just saw, the information that we can get back through Skype for Business is a bit of a social engineers dream.  So you've got the department, you've got the office location they work in, you've got even whether they're online or offline.  Additionally, this does say online mobile online desktop.  So I've never fully seen that work in a useful way, but that options there.  You can also get email address phone number. And this note here is any status message that they've set.  So those quite frequently I've seen people will put on there about annual leave if they're going to be out of the office.  So obviously again, as far as social engineering goes, you know what office they're in, you know, the name, email address, what their job title is, you know, they're going to be out of the office.  So there's a lot of information for maybe even being able to turn up and say, you know, I'm supposed to be meeting so and so or, or even impersonating someone and you know they're definitely not going to be in the office.  So so I was saying the problem is some of this extra information does take a large number of additional requests.  So so yeah, by all means tick all, but just beware that might take a very long time. And yeah, those are the options you've got.  So carnivore pulls the internal dress book back using people search on the UC with the UC WA API.  So this does mean that we're essentially having to search letter by letter a through Z. However, there's an upper limit of 100 on the amount of responses it returns.  And there isn't a next link that we can say is the first 100 now go to the next link for the next, you know, however many and so on.  So basically what we have to resort to is searching by digraphs and try graphs. So essentially a B a C a D and then even a B C a B D a B E.  And so basically we can then take either the from the top statistically likely usernames list, we can do all of the likely and unique kind of three letters that are there, or you can do all possible to character combinations.  So what's interesting and fun about the UC WA API is that there doesn't seem to be much rhyme or reason as to the way that works in terms of what we get back.  So to take an example, if we're looking for every pool in the domain so we know there's four, and we search for P, you get back 150 results.  So we're just going to get the top 100. There's two polls in there. So then we search for PA, we get back 20 results. But this time there's three pools.  So we've got one extra. But for some reason, even though we haven't hit the upper limit, we've still not actually got back every pool who's in the domain.  So then we search for PA you. And now we get this mysterious rogue fourth pool that we've never seen before.  So essentially, in the interest of me keeping my sanity, I've stuck with diagrams and try graphs. It's possible you might want to go on and do quad graphs and quink graphs and whatever else they're called.  However, so when I looked at this with the common try graphs, then and then with every possible three character combination that actually only added an additional I think it was maybe even one user in a domain of 6000.  And the difference is common does 2249 requests, whereas every possible was about 17 and a half thousand. So all of that for one additional user that as I've said was kind of hiding away.  And we weren't able to get otherwise. So essentially, hopefully that explains the kind of options on the address list a little bit more.  One additional kind of side note. So it's fairly uncommon, but I've seen it where a misconfigured Microsoft Web App proxy basically meant that when you off to the first server, and it gives you back the token and then you try and use that against the applications end point.  And then it's essentially sends it to the wrong place or you've been off to the wrong box. And so it then doesn't like it. That actually also stopped the legitimate Skype client from being able to authenticate, you know, to Skype.  However, now carnival is able to detect that it reoffs to the correct box and carries on. So basically carnival is able to connect and carry on using the API, even when the legitimate client actually couldn't.  Okay, so now the final post compromise function, which is meeting snooper. And so unfortunately my lab servers stopped working for this. So we have to make do with screenshots.  Okay, so as you can see here, this is the meeting snooper tab. So once you've compromised the user, if you've got Skype available. So this uses the UCWA API as well.  And then you can go here and you have to choose. You have to pick the compromised user that you want to use there.  So now we can either choose basically we can do this for all compromised users or just a selected user. Now one thing to say is that this only picks up currently scheduled meetings.  Obviously, so basically we can run this throughout the day multiple times or you know at the start of the day you could run it see if any new meetings have been added and then kind of keep running it to pull back new information.  So first of all, it dumps the standard dial in information to the output log. So if you've ever had an email inviting you to a Skype meeting, this will look fairly familiar to you. So you've got the internal number you can dial and then a number for each country or city within that country.  And so now apologies for how utterly rubbish this looks. As I said, my training lab unfortunately kind of packing in at the key moment there. But yeah, so just stress this isn't an exploit or a zero day.  It's basically highlighting what's already possible through kind of weaponization of the UCWA API for attackers. Obviously it does depend on compromised credentials.  But basically, so far this tool has shown how we can go from external over the internet to kind of complete compromise and to this point, being able to dump out scheduled meetings for compromised users.  So one thing to say is that when kind of using this tool on on jobs, then often you find if you're going to get anyone, you probably are going to get like 50 to 100 users. And obviously, in that case, then this becomes more interesting, because you know one user might have one meeting that week.  But if you've got 50 users, then maybe you've got someone who's a little bit more interesting. So you can then see here, what happens when you run this tool is that it gives you information for each meeting that compromised user has scheduled.  So the conference ID there is the pin. So basically when you dial in, you dial into the phone number and ask you for a pin, and that's that conference ID. And basically that conference ID is unique to that user.  So when you dial in, you'll be impersonating whoever it is that you've compromised. So for example, this you dial in, you put the pin and then you show up as being, say Chris Nevin guest.  Now, obviously, if the people in the meeting are kind of using the desktop application, then maybe it would look weird to have multiple Chris Nevin guests. If everyone's using the phone to dial in, I'm not sure that they would know this is a tool at all.  And in fact, even if they did see these two Chris Nevin guests, you know, how likely is it that people are going to assume, oh, this is someone impersonating and joining in and listening, as opposed to, you know, maybe there's some weird bug that's happening.  So the information we get here includes the subject of the meeting and the attendees. So obviously these meetings here I've scheduled just to kind of demonstrate.  But obviously this could be a lot more juicy. So for example, you've compromised the user, you know, from their address book, they're the head of financial fraud. And this meeting subject shows it's the weekly financial crime investigation update.  So obviously you can see why this would be kind of concerning for an organization if this was possible. And because, again, without any exploit, any need for any further phishing or payloads being executed, you've basically gone from being over the internet to being able to listen in on and even record the sensitive  meetings essentially impersonating that user. And so on the right you can see the lobby bypass enabled. That basically means that if you dial in does it bypass the lobby. If that's enabled that means you're not even in a waiting room that someone has to let you in.  So the join URL. If you go to that, you can join the meeting and you can basically enter a name of your choice. So obviously one thing you could do is again, you've done the address book.  And, you know, is there a social engineering angle, maybe you could kind of choose your name based on that, potentially might be more likely to get caught, whereas actually just dialing in and there being two of the compromised user is maybe less trouble in.  So the another thing to say is that the API basically only seems to give the meeting expiry. So that's two weeks after the meeting ends. So carnival will take off, it will remove the two weeks for you automatically.  And then it's kind of maybe you'll need to do some kind of common sense around that. So for example, you see the top meeting there.  We actually have been able to pull is that the meeting ends at 1130. Now I've set the subject for that one to be the time while I was troubleshooting.  So you can see that actually that meeting starts at 11. As I say, normally you wouldn't get that information, because that's the subject.  So obviously, yeah, if you apply some common sense to it, then you can see, OK, the meeting ends at 1130, it probably starts at 11 or even 1030.  So yeah, so that's the meeting snooping, what you get back from it, basically.  So there are a couple of extra points to mention, which are that this only seems to be able to pull back self scheduled meetings.  So again, doesn't fully make sense to me because obviously in outlook or something, you don't just see meetings you've scheduled, you see every meeting that you're scheduled to be a part of.  Unfortunately, we're not able to get that through this tool.  So yeah, and then also meeting and time only, as I said before.  Now there are some weird edge cases with that. So for example, I set a recurring meeting. So the only information we get back is that it ends on the 26th of December 2022, which obviously isn't that useful.  Again, maybe you could figure out, OK, that's a Friday, it's a half 10. So maybe it's every Friday.  But again, we can't get that back through the API, unfortunately.  Okay, so Office 365. So I'm not going to demo this. So what I've been showing so far is basically just my lab.  And so yeah, we're not going to demo Office 365, but I'm going to talk you through how Carnival works.  So for example, sorry, one thing to say is that username enumeration that doesn't require a password guest has been quite widely covered.  So there's things like 0365 or 0365 enum. So I'm just going to quickly kind of get into password spraying and give some key pointers.  So as I said before, federated as a win. So just the usual active directory rules will apply to lockouts.  But again, that kind of doesn't include the extremely robust Office 365 rules.  So as I've said, there's a link that I'm about to show you where you can find out if an organization is federated or not.  If it is, you'll get back the ADFS server location and Carnival will add that automatically.  So if it's not federated, we can still spray, sorry, we have to spray the Office portal, but then we can also determine if a user and password is valid,  even if we have MFA on there. And sorry, I should have said again, with federated, if it's federated, you have to spray ADFS and you can't spray the Office portal.  You won't get back anything interesting, anything useful. So password spray countermeasures for Office 365.  So they have things like trusted versus untrusted network have separate bad password counts.  So again, if you're from the untrusted side, which presumably you would be from an untrusted network, then, you know, your password spray is adding to account of everyone else in the world.  So again, lockout is fairly frequent and quick.  But from Microsoft side, obviously that's designed so that then the genuine user can still sign in while on their corporate VPN or something like that.  So obviously good security measures but difficult from a red team perspective.  So first of all, to find out if the organization is federated. So this is an example request here.  So the username itself is relevant. It's just the domain.com that we're looking for.  And the response here. So if they were federated, that would say federated instead of managed.  And it can also include some kind of boilerplate text. So for example, is keep me signed in disabled.  Obviously that one might be interesting from a red team perspective because maybe it hints that they have fairly good security and they've had the configuration looked at because users can't just stay signed in forever.  You also get the Federation brand name there and you can get back, you know, logo information and that kind of thing.  And so also if this said federated, then we would see the location of the ADFS authentication endpoint there as well.  So for password spraying, this is how Carnivore does it. So this is the endpoint that we're hitting.  There's the username and the password. So the client ID and the scope, obviously that could be tweaked to maybe be a little bit more realistic or representative.  But this is what Carnivore uses.  And so this first one is if there's an invalid password. Now obviously the actual response here says invalid username or password.  So obviously that seems like maybe that's going to be a bit tricky for us. Is it the username or is it the password? We're not fully sure.  But then if the username is incorrect, then we get this message back. The user account does not exist in that directory.  So obviously from that we can tell the previous response means the password's wrong, not the username.  And just to also mention there where it says email hidden, I've not added that. That's the actual response.  So then this is a valid user and password without NFA. So again, this is specific to the request that I make in Carnivore.  So because we gave a client ID that doesn't exist, then if the username and password is correct, you'd get this unauthorized client and a message that that application doesn't exist.  Because obviously it's not a proper client ID.  And again, so if it's valid user and password with MFA, then again we get this invalid grant.  But now it's telling us that it's due to configuration meaning that you need to supply multi-factor authentication.  So again, username and password is correct, but you need MFA.  So outro very briefly. Yes, so almost forgot to put it in, but here's a link to the tool itself.  So obviously you can go there and download the latest version and any issues or anything that you want to bring up there.  I'll be happy to try and help wherever I can. So thank you for listening.  Hopefully it's been useful and they enjoy carnivoring.
DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_0_263.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_264_851.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_852_1223.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_1224_1319.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_1320_9491.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_9492_11099.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_11100_11231.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_11232_11375.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_11376_12179.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_12180_12287.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_12288_12611.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_12612_12803.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_12804_13343.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_13344_14639.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_14640_15215.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_15216_15263.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_15264_15671.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_15672_17483.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_17484_17663.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_17664_19679.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_19680_20771.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_20772_20903.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_20904_20987.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_20988_25739.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_25740_30671.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_30672_31715.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_31716_32039.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_32040_32183.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_32184_32387.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_32388_32579.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_32580_32795.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_32796_33203.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_33204_33551.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_33552_33623.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_33624_35579.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_35580_35735.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_35736_35891.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_35892_35963.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_35964_36491.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_36492_37835.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_37836_37883.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_37884_37955.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_37956_39683.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_39684_41627.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_41628_44519.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_44520_48527.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_48528_48707.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_48708_51611.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_51612_52343.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_52344_52391.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_52392_54515.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_54516_54731.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_54732_58607.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_58608_58655.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_58656_60203.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_60204_61427.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_61428_61895.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_61896_61943.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_61944_62195.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_62196_69311.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_69312_69419.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_69420_70679.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_70680_71555.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_71556_74099.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_74100_74459.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_74460_75683.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_75684_76223.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_76224_76667.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_76668_77195.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_77196_77867.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_77868_78371.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_78372_78467.png DEF_CON_Safe_Mode_Demo_Labs__-_Chris_Nevin_-_Carnivore_78468_78956.png