1 00:00:01,260 --> 00:00:02,790 - Let's welcome Christopher on 2 00:00:02,790 --> 00:00:04,710 and he is a first time speaker, 3 00:00:04,710 --> 00:00:07,657 so everybody knows what that means. 4 00:00:07,657 --> 00:00:10,824 (audience applauding) 5 00:00:21,090 --> 00:00:22,193 How is it going? 6 00:00:22,193 --> 00:00:23,360 - Good cheers. 7 00:00:24,750 --> 00:00:25,850 Good evening everyone. 8 00:00:27,300 --> 00:00:30,180 So I'm here to talk about SCCM, 9 00:00:30,180 --> 00:00:32,793 a couple of passwords that it stores. 10 00:00:33,630 --> 00:00:36,780 How to get them from different attacker perspectives, 11 00:00:36,780 --> 00:00:37,920 and a little bit of my story 12 00:00:37,920 --> 00:00:40,053 in figuring out how this all works. 13 00:00:41,220 --> 00:00:44,970 So I started my career in cyber security 14 00:00:44,970 --> 00:00:48,510 around eight years ago, as a penetration tester 15 00:00:48,510 --> 00:00:53,430 with an interest in internal infrastructure testing. 16 00:00:53,430 --> 00:00:55,860 Quickly pivoted to doing some red teaming as well, 17 00:00:55,860 --> 00:00:57,480 and part of that skill set 18 00:00:57,480 --> 00:01:02,220 was needing to develop the ability to attack AD. 19 00:01:02,220 --> 00:01:04,860 And after doing a couple of assessments in that line, 20 00:01:04,860 --> 00:01:08,130 I realized that oftentimes AD Security 21 00:01:08,130 --> 00:01:11,520 isn't necessarily controlled by AD itself, 22 00:01:11,520 --> 00:01:13,110 it's controlled by the configuration 23 00:01:13,110 --> 00:01:16,773 of large scale enterprise solutions like SCCM. 24 00:01:17,820 --> 00:01:22,820 So my story with SCCM started in a client engagement 25 00:01:23,370 --> 00:01:27,990 where a client had configured it to use network boot. 26 00:01:27,990 --> 00:01:31,893 So for the uninitiated, like I was at the time, 27 00:01:33,420 --> 00:01:35,160 this is what that looks like. 28 00:01:35,160 --> 00:01:38,730 If we're connected to the same network as a SCCM server 29 00:01:38,730 --> 00:01:42,150 that's set up for network boot, 30 00:01:42,150 --> 00:01:45,810 we can prompt to do a network boot, 31 00:01:45,810 --> 00:01:47,610 it'll get an IP address, 32 00:01:47,610 --> 00:01:50,670 figure out where the network boot server is, 33 00:01:50,670 --> 00:01:53,220 and then start downloading an OS image 34 00:01:53,220 --> 00:01:55,500 that it's going to boot into. 35 00:01:55,500 --> 00:01:59,193 After it's done downloading that OS image, 36 00:02:00,240 --> 00:02:02,640 it proceeds to boot it, 37 00:02:02,640 --> 00:02:06,873 and at the end of this boot process we end up 38 00:02:09,180 --> 00:02:12,630 in something called a Windows Preinstallation Environment, 39 00:02:12,630 --> 00:02:16,140 so WinPE, it's a stripped down version of Windows 40 00:02:16,140 --> 00:02:19,770 that has like the bare minimum libraries, no Explorer, 41 00:02:19,770 --> 00:02:21,210 and it can run things like 42 00:02:21,210 --> 00:02:23,883 a Configuration Manager client like this one. 43 00:02:24,780 --> 00:02:27,030 at the end of it's set up 44 00:02:27,030 --> 00:02:28,860 we get prompted with this password screen. 45 00:02:28,860 --> 00:02:30,780 So if we look at the screen, 46 00:02:30,780 --> 00:02:33,180 it's asking us for some random password. 47 00:02:33,180 --> 00:02:35,400 On that client engagement that I was on 48 00:02:35,400 --> 00:02:36,870 the only thing the client gave me 49 00:02:36,870 --> 00:02:38,673 was the password for the screen. 50 00:02:39,780 --> 00:02:41,970 So put in the password, 51 00:02:41,970 --> 00:02:44,220 click through a couple of dialogue boxes 52 00:02:44,220 --> 00:02:47,250 and I ended up with a VM that was domain-joined 53 00:02:47,250 --> 00:02:50,040 that had all of the clients security software 54 00:02:50,040 --> 00:02:51,510 and software installed. 55 00:02:51,510 --> 00:02:53,160 This kind of blew my mind at the time 56 00:02:53,160 --> 00:02:55,200 because I knew that if I'm ending up 57 00:02:55,200 --> 00:02:57,090 with a domain-joined machine, 58 00:02:57,090 --> 00:03:00,660 then there has to be some domain codes somewhere 59 00:03:00,660 --> 00:03:02,790 that are doing the domain-joining. 60 00:03:02,790 --> 00:03:04,440 So I chatted to the client, 61 00:03:04,440 --> 00:03:06,960 we figured that let's go searching for the creds, 62 00:03:06,960 --> 00:03:11,460 see what the creds are, and that's where the journey began. 63 00:03:11,460 --> 00:03:13,410 So one of the first things that we discovered 64 00:03:13,410 --> 00:03:16,620 is in a lot of these Windows PE Environments, 65 00:03:16,620 --> 00:03:20,970 if you press F8, it will pop a system shell. 66 00:03:20,970 --> 00:03:23,670 Now, that's more or less useful 67 00:03:23,670 --> 00:03:26,970 depending on which part of the deployment process you're in, 68 00:03:26,970 --> 00:03:28,170 but it gives you the ability 69 00:03:28,170 --> 00:03:30,633 to interact with the environment and run tools. 70 00:03:31,680 --> 00:03:33,540 One of the interesting things that you can do 71 00:03:33,540 --> 00:03:35,670 once you have this command shell there, 72 00:03:35,670 --> 00:03:38,520 is you can dump out the environment variables. 73 00:03:38,520 --> 00:03:42,930 So after you start an operating system install, 74 00:03:42,930 --> 00:03:44,820 you can write a VB script file 75 00:03:44,820 --> 00:03:47,130 that dumps out the environment variables, 76 00:03:47,130 --> 00:03:49,437 and one of the really interesting ones is 77 00:03:49,437 --> 00:03:53,400 _SMSTS reserved one and reserve two 78 00:03:53,400 --> 00:03:56,610 Those are the Network Access Account creds 79 00:03:56,610 --> 00:03:58,890 that the Windows PE Environment uses 80 00:03:58,890 --> 00:04:01,080 to talk to the SCCM server 81 00:04:01,080 --> 00:04:03,150 and download the software that it's going to install. 82 00:04:03,150 --> 00:04:05,310 So this is stuff like the operating system image, 83 00:04:05,310 --> 00:04:08,100 and the individual software packages 84 00:04:08,100 --> 00:04:09,630 that need to get installed. 85 00:04:09,630 --> 00:04:12,540 This however, is not the set of creds that are used 86 00:04:12,540 --> 00:04:16,680 to domain-join the machine, so we carried on our search. 87 00:04:16,680 --> 00:04:20,370 And eventually, after interrupting install midway 88 00:04:20,370 --> 00:04:22,233 and mounting it in a different VM, 89 00:04:23,490 --> 00:04:28,490 I figured out that if you look at the Unattended.xml file 90 00:04:29,520 --> 00:04:33,150 after you've started an operating system deployment 91 00:04:33,150 --> 00:04:36,660 in the C Windows Panther Unattended folder, 92 00:04:36,660 --> 00:04:40,020 you actually find the domain-joining creds 93 00:04:40,020 --> 00:04:42,280 that this machine is gonna use to domain 94 00:04:43,140 --> 00:04:44,540 yeah, to join to the domain. 95 00:04:45,420 --> 00:04:46,980 That was really interesting 96 00:04:46,980 --> 00:04:49,110 in this specific client's estate 97 00:04:49,110 --> 00:04:51,390 because it ended up being that 98 00:04:51,390 --> 00:04:55,080 these credentials had workstation administrative access 99 00:04:55,080 --> 00:04:57,870 to all the workstation and laptops 100 00:04:57,870 --> 00:04:59,760 across their entire AD environment, 101 00:04:59,760 --> 00:05:00,930 which was a big deal for them, 102 00:05:00,930 --> 00:05:03,713 they had spent a lot of effort trying to harden their AD. 103 00:05:04,620 --> 00:05:07,440 Over the years, we've seen this kind of story repeated, 104 00:05:07,440 --> 00:05:09,510 so I've pulled the Network Access Account 105 00:05:09,510 --> 00:05:12,270 on certain clients and in one estate, 106 00:05:12,270 --> 00:05:15,150 it ended up having administrative access 107 00:05:15,150 --> 00:05:17,340 to the SCCM service itself, 108 00:05:17,340 --> 00:05:19,410 and then we could do some lateral movement 109 00:05:19,410 --> 00:05:22,890 and credential theft to get domain administrative access. 110 00:05:22,890 --> 00:05:25,110 In other states it's actually configured 111 00:05:25,110 --> 00:05:27,930 as domain admin out of the box. 112 00:05:27,930 --> 00:05:31,650 So kind of the TLDR of this is, 113 00:05:31,650 --> 00:05:33,180 there was sufficient evidence 114 00:05:33,180 --> 00:05:35,970 to figure out that these kinds of credentials 115 00:05:35,970 --> 00:05:40,293 that are exposed to the PXE boot environment, 116 00:05:41,370 --> 00:05:44,400 a lot of times have quite privileged access 117 00:05:44,400 --> 00:05:46,770 over the active directory environment that they're in. 118 00:05:46,770 --> 00:05:49,560 So they're kind of like a worthwhile target going for, 119 00:05:49,560 --> 00:05:51,060 and it's worth understanding 120 00:05:51,060 --> 00:05:54,930 how to pull those credentials consistently. 121 00:05:54,930 --> 00:05:57,000 So that was my target, 122 00:05:57,000 --> 00:05:58,650 I knew what I wanted to go after. 123 00:06:00,540 --> 00:06:04,660 And the specific thing that we're looking at here 124 00:06:05,889 --> 00:06:09,150 is Microsoft Endpoint Configuration Manager, or SCCM, 125 00:06:09,150 --> 00:06:12,600 or System Center Configuration Manager, or Config Manager. 126 00:06:12,600 --> 00:06:14,940 In this talk you're gonna hear me use all of those terms 127 00:06:14,940 --> 00:06:17,520 they refer to the exact same product, 128 00:06:17,520 --> 00:06:21,390 it's basically a software management product 129 00:06:21,390 --> 00:06:24,690 developed by Microsoft that is used to deploy, 130 00:06:24,690 --> 00:06:29,250 update, manage, and manage software on workstations 131 00:06:29,250 --> 00:06:32,250 and servers across an estate. 132 00:06:32,250 --> 00:06:34,740 It's used to patch all kinds of machines 133 00:06:34,740 --> 00:06:37,560 from the most critical domain controllers 134 00:06:37,560 --> 00:06:38,760 and exchange servers 135 00:06:38,760 --> 00:06:42,453 to every single employee workstation and laptop. 136 00:06:44,460 --> 00:06:47,010 So probably the most important thing 137 00:06:47,010 --> 00:06:49,770 that we need to know going into this is, 138 00:06:49,770 --> 00:06:52,680 what kind of credentials are we targeting? 139 00:06:52,680 --> 00:06:54,750 We've already talked about two kinds, 140 00:06:54,750 --> 00:06:56,310 the network access credentials 141 00:06:56,310 --> 00:06:58,290 and the domain-joining credentials, 142 00:06:58,290 --> 00:07:00,780 but I've actually found three locations 143 00:07:00,780 --> 00:07:03,390 where credentials can be configured 144 00:07:03,390 --> 00:07:05,820 where those credentials will be pushed down 145 00:07:05,820 --> 00:07:07,953 to Configuration Manager clients. 146 00:07:08,970 --> 00:07:11,253 So the first is the Network Access Account. 147 00:07:12,120 --> 00:07:14,880 Again, this is used primarily by Windows PE 148 00:07:14,880 --> 00:07:16,320 because it's not domain-joined, 149 00:07:16,320 --> 00:07:18,120 so it needs some sets of credentials 150 00:07:18,120 --> 00:07:21,240 to talk to SCCM to download software. 151 00:07:21,240 --> 00:07:24,120 There's a lot of recent research that come out 152 00:07:24,120 --> 00:07:26,580 on how to pull those credentials. 153 00:07:26,580 --> 00:07:29,100 And I'm going to in this talk add 154 00:07:29,100 --> 00:07:31,230 kind of the operating system deployment 155 00:07:31,230 --> 00:07:35,820 and PXE deployment method of pulling these credentials 156 00:07:35,820 --> 00:07:38,070 to the current view. 157 00:07:38,070 --> 00:07:41,850 In order to properly understand the second place 158 00:07:41,850 --> 00:07:44,580 that credentials can be configured, 159 00:07:44,580 --> 00:07:49,580 we need to understand how task sequences work in SCCM. 160 00:07:49,740 --> 00:07:53,400 So task sequences are ultimately a set of instructions 161 00:07:53,400 --> 00:07:56,010 that allows us to take a blank machine 162 00:07:56,010 --> 00:07:59,100 and apply certain steps to it 163 00:07:59,100 --> 00:08:02,400 in order to make a domain-joined machine 164 00:08:02,400 --> 00:08:04,350 that has a bunch of software installed. 165 00:08:06,330 --> 00:08:08,850 So inside a Network Boot Environment, 166 00:08:08,850 --> 00:08:10,980 the task sequence selection screen 167 00:08:10,980 --> 00:08:14,850 is effectively what is shown in the screenshot here, 168 00:08:14,850 --> 00:08:18,660 and practically speaking in real life environment, 169 00:08:18,660 --> 00:08:20,760 each of the different types of machines 170 00:08:20,760 --> 00:08:21,810 that you want to build 171 00:08:21,810 --> 00:08:25,233 will end up having an associated task sequence. 172 00:08:26,220 --> 00:08:30,510 Those task sequences are made up of task sequence steps 173 00:08:30,510 --> 00:08:34,470 that define the order in which you need to do operations 174 00:08:34,470 --> 00:08:37,053 in order to get a working machine out. 175 00:08:37,890 --> 00:08:42,890 One of the steps is to domain join the machine, 176 00:08:43,710 --> 00:08:46,200 this is actually called Apply Network Settings 177 00:08:46,200 --> 00:08:48,210 and there's a nice convenient box 178 00:08:48,210 --> 00:08:50,730 inside the Configuration Manager console, 179 00:08:50,730 --> 00:08:53,610 where you can set these credentials. 180 00:08:53,610 --> 00:08:55,650 There's also additional places 181 00:08:55,650 --> 00:08:58,020 where these credentials can be configured, 182 00:08:58,020 --> 00:09:01,320 so I'm just gonna run through them really, really quickly. 183 00:09:01,320 --> 00:09:04,920 So one of the features that SCCM supports 184 00:09:04,920 --> 00:09:07,593 is the ability to make a new reference image. 185 00:09:08,430 --> 00:09:10,650 That reference image needs to be written 186 00:09:10,650 --> 00:09:14,040 to some kind of network share in order to save it. 187 00:09:14,040 --> 00:09:15,870 And in order to write to a network share 188 00:09:15,870 --> 00:09:17,190 you obviously need credentials, 189 00:09:17,190 --> 00:09:20,643 so it allows space for those credentials to be configured. 190 00:09:21,480 --> 00:09:25,140 The second place where you can configure credentials 191 00:09:25,140 --> 00:09:28,110 is that when you build a machine, you can obviously set 192 00:09:28,110 --> 00:09:30,270 the local admin password of the machine. 193 00:09:30,270 --> 00:09:33,810 This happens before any software is installed, 194 00:09:33,810 --> 00:09:38,810 so lapse would take precedence over this, 195 00:09:39,000 --> 00:09:42,660 since it would happen after the machine is built. 196 00:09:42,660 --> 00:09:45,900 You can run arbitrary commands as any domain user, 197 00:09:45,900 --> 00:09:47,640 but then you have to provide the credentials 198 00:09:47,640 --> 00:09:48,960 for that domain user. 199 00:09:48,960 --> 00:09:52,350 And lastly, you can connect to an arbitrary network folder 200 00:09:52,350 --> 00:09:54,767 in order to pull files down, 201 00:09:54,767 --> 00:09:58,410 if that's part of you building a new machine. 202 00:09:58,410 --> 00:10:01,290 And as part of that, you need to provide the credentials 203 00:10:01,290 --> 00:10:04,090 that you're gonna use to connect to that network folder. 204 00:10:05,220 --> 00:10:09,900 And lastly, in order to understand the third place 205 00:10:09,900 --> 00:10:11,010 that I found credentials, 206 00:10:11,010 --> 00:10:12,840 you need to understand how collections work 207 00:10:12,840 --> 00:10:14,640 in Configuration Manager. 208 00:10:14,640 --> 00:10:18,510 So collections are a concept 209 00:10:18,510 --> 00:10:20,820 where we want to apply certain settings 210 00:10:20,820 --> 00:10:22,500 to an entire group of machines 211 00:10:22,500 --> 00:10:24,720 rather than to machines individually. 212 00:10:24,720 --> 00:10:26,070 So what we can do is, 213 00:10:26,070 --> 00:10:28,650 we can create a collection of those machines, 214 00:10:28,650 --> 00:10:29,820 add all the machines 215 00:10:29,820 --> 00:10:32,070 that we want to apply these settings to, 216 00:10:32,070 --> 00:10:33,450 to that given collection, 217 00:10:33,450 --> 00:10:37,320 and then apply things like task sequences to the collection. 218 00:10:37,320 --> 00:10:39,720 Now, collections have an interesting feature 219 00:10:39,720 --> 00:10:41,760 called collection variables, 220 00:10:41,760 --> 00:10:43,860 these are effectively environment variables 221 00:10:43,860 --> 00:10:47,700 where you can specify a name and a value 222 00:10:47,700 --> 00:10:49,620 for that collection variable, 223 00:10:49,620 --> 00:10:51,600 and these get pushed to all of the machines 224 00:10:51,600 --> 00:10:53,280 that are in a given collection. 225 00:10:53,280 --> 00:10:55,720 Now, there's nothing specifically requiring 226 00:10:56,732 --> 00:10:59,610 these collection variables to store passwords, 227 00:10:59,610 --> 00:11:01,230 but interestingly enough, 228 00:11:01,230 --> 00:11:04,200 SCCM treats it as if it's sensitive, 229 00:11:04,200 --> 00:11:06,090 so it still encrypts it. 230 00:11:06,090 --> 00:11:08,523 It's possible to use these four credentials, 231 00:11:09,750 --> 00:11:11,400 if they exist and they're configured, 232 00:11:11,400 --> 00:11:12,690 it's worth pulling them down 233 00:11:12,690 --> 00:11:15,003 to see if there is anything sensitive in them. 234 00:11:16,680 --> 00:11:21,240 And the last thing before we dig in to how things work, 235 00:11:21,240 --> 00:11:26,240 and how PXE boot in Configuration Manager works 236 00:11:26,550 --> 00:11:28,023 is some terminology. 237 00:11:29,010 --> 00:11:33,210 So as we have discussed something like a task sequence 238 00:11:33,210 --> 00:11:36,180 needs to pull down software from a server 239 00:11:36,180 --> 00:11:39,510 in order to apply it to this machine that you want to build. 240 00:11:39,510 --> 00:11:42,210 That software, whether it's an operating system image, 241 00:11:42,210 --> 00:11:45,270 whether it's an MSI, whether it's EXE installer 242 00:11:45,270 --> 00:11:47,460 is what is known as content. 243 00:11:47,460 --> 00:11:51,810 Content is downloaded from a specific server role in SCCM 244 00:11:51,810 --> 00:11:53,703 called distribution points. 245 00:11:54,570 --> 00:11:56,430 A Configuration Manager client, 246 00:11:56,430 --> 00:11:57,960 like the one that we saw running 247 00:11:57,960 --> 00:11:59,850 inside the Windows PE Environment 248 00:11:59,850 --> 00:12:03,780 has to authenticate to the distribution point 249 00:12:03,780 --> 00:12:07,980 in order to prove that it has the authorization, I guess, 250 00:12:07,980 --> 00:12:11,820 to access the content that it's trying to access. 251 00:12:11,820 --> 00:12:16,440 Similarly, in terms of other things 252 00:12:16,440 --> 00:12:18,090 that a client needs to do, 253 00:12:18,090 --> 00:12:20,820 that might have a bunch of configuration settings 254 00:12:20,820 --> 00:12:24,330 that it uses to control which software packages 255 00:12:24,330 --> 00:12:26,073 it decides to download. 256 00:12:27,540 --> 00:12:29,340 And those configuration settings 257 00:12:29,340 --> 00:12:32,160 are what's known as a policy. 258 00:12:32,160 --> 00:12:35,160 So policies are not downloaded from distribution points, 259 00:12:35,160 --> 00:12:38,430 they're downloaded from a different SCCM server 260 00:12:38,430 --> 00:12:39,510 called a management point. 261 00:12:39,510 --> 00:12:41,940 Again, the Configuration Manager client 262 00:12:41,940 --> 00:12:44,550 needs to authenticate to the management point 263 00:12:44,550 --> 00:12:46,140 to prove that it is authorized 264 00:12:46,140 --> 00:12:48,303 to ask for the policies that apply to it. 265 00:12:49,710 --> 00:12:52,500 All right, now that we've covered all of that, 266 00:12:52,500 --> 00:12:54,780 how does network booting actually work 267 00:12:54,780 --> 00:12:56,730 in Configuration Manager? 268 00:12:56,730 --> 00:13:01,560 So one bit of context that's kind of useful to understand 269 00:13:01,560 --> 00:13:04,170 is that network booting and Configuration Manager 270 00:13:04,170 --> 00:13:07,290 is actually part of a broader set of functionality 271 00:13:07,290 --> 00:13:09,150 that Configuration Manager supports 272 00:13:09,150 --> 00:13:11,280 called operating system deployment. 273 00:13:11,280 --> 00:13:13,540 Operating system deployment mostly 274 00:13:15,120 --> 00:13:18,750 is made up of a task sequence 275 00:13:18,750 --> 00:13:22,830 that is aimed at deploying a new OS to a machine, 276 00:13:22,830 --> 00:13:26,100 and the policy settings that are needed 277 00:13:26,100 --> 00:13:28,020 in order to make sure that, 278 00:13:28,020 --> 00:13:30,420 that task sequence applies successfully. 279 00:13:30,420 --> 00:13:32,910 There's multiple ways to kick this off, 280 00:13:32,910 --> 00:13:34,470 the video that we saw in the beginning 281 00:13:34,470 --> 00:13:36,300 was using network boot 282 00:13:36,300 --> 00:13:39,000 in order to kick-off operating system deployment, 283 00:13:39,000 --> 00:13:41,280 but you can actually make ISO files, 284 00:13:41,280 --> 00:13:44,250 or WIM files, or a USB drive 285 00:13:44,250 --> 00:13:47,520 that has the necessary files on that you can boot off of 286 00:13:47,520 --> 00:13:51,060 in order to start a new operating system deployment. 287 00:13:51,060 --> 00:13:52,980 What's important to note about this, 288 00:13:52,980 --> 00:13:55,650 is regardless of what method you use 289 00:13:55,650 --> 00:13:58,530 to start your operating system deployment, 290 00:13:58,530 --> 00:14:01,410 all of them boot into a Windows PE Environment, 291 00:14:01,410 --> 00:14:03,780 run a Configuration Manager client, 292 00:14:03,780 --> 00:14:07,173 and then start to talk to SCCM to figure out what to do. 293 00:14:08,610 --> 00:14:12,090 Okay, so how does network booting work? 294 00:14:12,090 --> 00:14:15,180 Well, first let's say we have a blank machine 295 00:14:15,180 --> 00:14:17,040 that doesn't have an OS on it. 296 00:14:17,040 --> 00:14:19,200 We plug it into the network, 297 00:14:19,200 --> 00:14:20,640 and the first thing that we're gonna do, 298 00:14:20,640 --> 00:14:21,780 is we're gonna press the key 299 00:14:21,780 --> 00:14:25,050 that makes the machine ask for a network boot. 300 00:14:25,050 --> 00:14:27,030 It's going to do a DHCP request 301 00:14:27,030 --> 00:14:28,410 to figure out its IP address, 302 00:14:28,410 --> 00:14:31,380 and to figure out where the network boot server is. 303 00:14:31,380 --> 00:14:33,240 It's then going to, 304 00:14:33,240 --> 00:14:36,210 after it identifies where that network would server is, 305 00:14:36,210 --> 00:14:39,330 it's going to make a specific DHCP request 306 00:14:39,330 --> 00:14:42,277 to that DHCP server to tell it, 307 00:14:42,277 --> 00:14:44,017 "Hey, I'm a PXE client, 308 00:14:44,017 --> 00:14:45,847 "I wanna figure out what's going on. 309 00:14:45,847 --> 00:14:47,857 "Please tell me what I need to download 310 00:14:47,857 --> 00:14:50,070 "in order to boot successfully." 311 00:14:50,070 --> 00:14:53,340 And then after it gets that information from, 312 00:14:53,340 --> 00:14:54,810 in this case a distribution point, 313 00:14:54,810 --> 00:14:59,070 distribution points are responsible for running PXE as well. 314 00:14:59,070 --> 00:15:01,830 After it gets an information from a distribution point, 315 00:15:01,830 --> 00:15:05,640 it will then use TFTP in order to download the files 316 00:15:05,640 --> 00:15:08,280 and kick off the operating system deployment method. 317 00:15:08,280 --> 00:15:11,100 So once we get all of that done, 318 00:15:11,100 --> 00:15:12,630 we'll boot into an environment, 319 00:15:12,630 --> 00:15:15,090 it will run a Configuration Manager client, 320 00:15:15,090 --> 00:15:16,860 and the Configuration Manager client 321 00:15:16,860 --> 00:15:20,310 will ask for some kind of password, okay. 322 00:15:20,310 --> 00:15:21,510 So what's this password for? 323 00:15:21,510 --> 00:15:24,300 It's not a username and a password, it's just the password. 324 00:15:24,300 --> 00:15:27,600 So what is being protected with this password? 325 00:15:27,600 --> 00:15:31,740 Well, if we investigate what's going on, on the SCCM server, 326 00:15:31,740 --> 00:15:36,740 when it receives that specific DHCP request from the client, 327 00:15:37,020 --> 00:15:39,480 it turns out that there's a specific folder, 328 00:15:39,480 --> 00:15:43,290 RemiInstall, SMSTemp and inside that folder 329 00:15:43,290 --> 00:15:45,300 specific files are being generated. 330 00:15:45,300 --> 00:15:50,130 So we see two files, a .var file and a .bcd file. 331 00:15:50,130 --> 00:15:53,310 The bcd file is your standard boot configuration file 332 00:15:53,310 --> 00:15:55,920 that tells the PXE client 333 00:15:55,920 --> 00:15:58,500 how to boot the image that it received. 334 00:15:58,500 --> 00:16:00,750 But the var file is actually quite interesting. 335 00:16:00,750 --> 00:16:04,320 this is what is known as a media variables file, 336 00:16:04,320 --> 00:16:08,310 and it actually contains all of the configuration 337 00:16:08,310 --> 00:16:09,720 information, I guess, 338 00:16:09,720 --> 00:16:11,850 that the client is going to be configured with 339 00:16:11,850 --> 00:16:15,570 so that it can authenticate later on to SCCM. 340 00:16:17,370 --> 00:16:20,940 Turns out the password is being used to derive a key 341 00:16:20,940 --> 00:16:22,803 that is used to encrypt this file. 342 00:16:24,060 --> 00:16:26,880 We can confirm that that's kind of what's going on 343 00:16:26,880 --> 00:16:29,160 because using our nice command shell 344 00:16:29,160 --> 00:16:31,350 that we have inside the WinPE Environment, 345 00:16:31,350 --> 00:16:34,680 we can start to analyze the files that are included. 346 00:16:34,680 --> 00:16:39,420 So WinPE is Windows running inside a Ram disk, 347 00:16:39,420 --> 00:16:42,090 it actually uses the xDrive by default, 348 00:16:42,090 --> 00:16:45,363 or at least SCCM WinPE does. 349 00:16:46,860 --> 00:16:50,400 And inside there, inside that specific drive, 350 00:16:50,400 --> 00:16:55,230 there is a Configuration Manager specific folder called SMS 351 00:16:55,230 --> 00:16:58,800 that contains all of the binaries and configuration data 352 00:16:58,800 --> 00:17:01,260 that this WinPE Environment needs 353 00:17:01,260 --> 00:17:03,180 in order to successfully boot 354 00:17:03,180 --> 00:17:06,300 and continue the operating system deployment method. 355 00:17:06,300 --> 00:17:07,920 Inside one of the bin folders, 356 00:17:07,920 --> 00:17:11,340 there's a Config file called TsBootShell.ini, 357 00:17:11,340 --> 00:17:13,560 and that defines the first command 358 00:17:13,560 --> 00:17:15,210 that's run inside WinPE. 359 00:17:15,210 --> 00:17:17,100 So we see that there's a reference 360 00:17:17,100 --> 00:17:19,200 to something called TsmBootstrap, 361 00:17:19,200 --> 00:17:23,370 and this is what the Configuration Manager client 362 00:17:23,370 --> 00:17:25,440 is inside a WinPE Environment, 363 00:17:25,440 --> 00:17:27,990 so that screen that we see that's asking for a password 364 00:17:27,990 --> 00:17:31,140 is the executable TsmBootstrap.exe, 365 00:17:31,140 --> 00:17:33,360 and we can see that it's called with reference 366 00:17:33,360 --> 00:17:38,040 to a different configuration directory XSMSData. 367 00:17:38,040 --> 00:17:41,340 Inside that folder there's a file called variables.dat, 368 00:17:41,340 --> 00:17:43,710 which suspiciously looks the same 369 00:17:43,710 --> 00:17:46,443 as that .var file that we saw earlier. 370 00:17:47,640 --> 00:17:51,150 And it turns out that this executable 371 00:17:51,150 --> 00:17:55,492 does all that DHCP stuff, pulls the .var file 372 00:17:55,492 --> 00:17:59,340 over TFTP and renames it variables.dat. 373 00:17:59,340 --> 00:18:01,680 So the password we type in the screen 374 00:18:01,680 --> 00:18:06,680 is then used to try and decrypt variables.dat, all right? 375 00:18:06,780 --> 00:18:08,850 So we know how it works at a high level, 376 00:18:08,850 --> 00:18:11,340 how do we turn this into an actual attack? 377 00:18:11,340 --> 00:18:16,340 Well, the first thing is we know that the password is used 378 00:18:17,730 --> 00:18:22,440 to try and decrypt this media variables file, 379 00:18:22,440 --> 00:18:24,360 so we need to get our hands on this file 380 00:18:24,360 --> 00:18:27,510 because we need to use the contents of that file 381 00:18:27,510 --> 00:18:30,570 for any kind of attack that we want to perform. 382 00:18:30,570 --> 00:18:35,100 I've written a set of Python tooling called PXE thief 383 00:18:35,100 --> 00:18:38,580 that I'm planning on releasing sometime this weekend, 384 00:18:38,580 --> 00:18:43,560 that implements all of these DHCP requests that are needed 385 00:18:43,560 --> 00:18:46,830 in order to first find where a PXE server is, 386 00:18:46,830 --> 00:18:50,760 and then prompt the Configuration Manager server 387 00:18:50,760 --> 00:18:54,060 in order to generate this media variables file 388 00:18:54,060 --> 00:18:55,470 and find the location of it, 389 00:18:55,470 --> 00:18:58,683 so that we can download it over TFTP. 390 00:19:00,240 --> 00:19:01,713 It looks like this, 391 00:19:02,640 --> 00:19:06,930 so if I run this video, yes, that worked properly. 392 00:19:06,930 --> 00:19:09,930 We can see that there's kind of like two main steps here, 393 00:19:09,930 --> 00:19:12,270 we issue a DHCP discovery request 394 00:19:12,270 --> 00:19:16,050 to find the location of an SCCM server, 395 00:19:16,050 --> 00:19:18,270 specifically a distribution point. 396 00:19:18,270 --> 00:19:21,240 And then once we figure out where the distribution point is, 397 00:19:21,240 --> 00:19:23,850 we issue a specific request to that server 398 00:19:23,850 --> 00:19:26,250 in order to generate the media variables file 399 00:19:26,250 --> 00:19:28,623 and find out where it is stored on disk. 400 00:19:29,730 --> 00:19:31,320 How does this work? 401 00:19:31,320 --> 00:19:33,480 Okay, first thing we need to start off with 402 00:19:33,480 --> 00:19:36,120 is with a DHCP discover. 403 00:19:36,120 --> 00:19:37,770 This is a very general thing, 404 00:19:37,770 --> 00:19:42,770 but if you try and prompt for a network boot, 405 00:19:43,140 --> 00:19:44,730 what is effectively happening is 406 00:19:44,730 --> 00:19:47,280 you're issuing a DHCP discover request 407 00:19:47,280 --> 00:19:50,220 with DHCP option 66 and 67, 408 00:19:50,220 --> 00:19:52,440 so you're asking for those options. 409 00:19:52,440 --> 00:19:57,210 If that environment is set up to support PXE boot, 410 00:19:57,210 --> 00:20:02,190 the main DCHP server will point you at the PXE boot server 411 00:20:02,190 --> 00:20:06,060 in the DHCP option 66 in the response. 412 00:20:06,060 --> 00:20:08,820 Once you have the location of that folder, 413 00:20:08,820 --> 00:20:11,220 you can then talk to a port on that folder 414 00:20:11,220 --> 00:20:16,220 that sets aside specifically for PXE support 4011. 415 00:20:16,470 --> 00:20:19,140 So we generate another DHCP request, 416 00:20:19,140 --> 00:20:22,590 but this time it's a request packet, not a discover packet. 417 00:20:22,590 --> 00:20:25,793 And we provide the options 93, 250, and 60 418 00:20:28,320 --> 00:20:33,060 inside our own request that identifies us as a client 419 00:20:33,060 --> 00:20:34,983 that is attempting to do a PXE boot. 420 00:20:35,910 --> 00:20:40,910 The only really weird option there is the DHCP option 250, 421 00:20:41,130 --> 00:20:43,230 it's a random binary string. 422 00:20:43,230 --> 00:20:44,820 Looking up the documentation, 423 00:20:44,820 --> 00:20:46,920 this is like a Microsoft specific thing 424 00:20:46,920 --> 00:20:50,010 where they identify the architecture of the machine 425 00:20:50,010 --> 00:20:52,800 that's asking for the network boot. 426 00:20:52,800 --> 00:20:54,870 I haven't actually run into any issues. 427 00:20:54,870 --> 00:20:58,890 The very first DHCP request packet that I captured 428 00:20:58,890 --> 00:21:01,590 has worked on every single SCCM server 429 00:21:01,590 --> 00:21:03,813 that supports PXE boot that I've run into. 430 00:21:04,740 --> 00:21:09,620 But yes, if theoretically it only supports x64 or x86, 431 00:21:11,310 --> 00:21:13,260 the string would need to, 432 00:21:13,260 --> 00:21:15,090 the string would be set to different values 433 00:21:15,090 --> 00:21:17,220 in order to match the architecture of the machine 434 00:21:17,220 --> 00:21:18,870 that's asking for a network boot. 435 00:21:20,037 --> 00:21:23,880 All right, so if we provide correct information 436 00:21:23,880 --> 00:21:28,170 and SCCM likes it, then inside the response, 437 00:21:28,170 --> 00:21:32,167 we get a DHCP option 243, 438 00:21:33,390 --> 00:21:36,933 which is another random binary string or hack string. 439 00:21:37,800 --> 00:21:40,020 Now, this hack string is kind of special 440 00:21:40,020 --> 00:21:42,090 because there is a field, 441 00:21:42,090 --> 00:21:44,610 a portion of it that is demarcated, 442 00:21:44,610 --> 00:21:47,430 it starts off with a hex bite 01, 443 00:21:47,430 --> 00:21:48,960 and then a length identifier. 444 00:21:48,960 --> 00:21:52,110 And then following that is the actual location 445 00:21:52,110 --> 00:21:54,900 of the media variables file on the DHCP. 446 00:21:54,900 --> 00:21:58,260 So if the DHCP server likes, 447 00:21:58,260 --> 00:22:01,680 if the SCCM server likes our DHCP request, 448 00:22:01,680 --> 00:22:04,200 it'll actually tell us where the media variables file is 449 00:22:04,200 --> 00:22:08,223 in this portion of DTP Option 243. 450 00:22:09,145 --> 00:22:12,930 All right, so that allows us to use any TFTP clients 451 00:22:12,930 --> 00:22:15,600 to download it because we know where it is, 452 00:22:15,600 --> 00:22:18,120 and then we can move on to the next step. 453 00:22:18,120 --> 00:22:20,820 Now, the important thing is, 454 00:22:20,820 --> 00:22:23,640 we can't really use a password as it is 455 00:22:23,640 --> 00:22:25,470 in order to attempt to decrypt the file. 456 00:22:25,470 --> 00:22:28,380 There has to be some kind of key derivation that's going on. 457 00:22:28,380 --> 00:22:31,260 So in addition to writing Python tooling 458 00:22:31,260 --> 00:22:34,320 to prompt the SCCM server 459 00:22:34,320 --> 00:22:37,170 into giving us the media variables file, 460 00:22:37,170 --> 00:22:39,780 I've also written a custom Hashcat module 461 00:22:39,780 --> 00:22:43,290 that implements the key derivation, so that we can perform 462 00:22:43,290 --> 00:22:45,570 a password guessing attack against it. 463 00:22:45,570 --> 00:22:49,920 I decided to use Hashcat because I like GPU support, 464 00:22:49,920 --> 00:22:54,450 and Hashcat seemed pretty far along in that space, 465 00:22:54,450 --> 00:22:58,140 so I went with it, it looks like this. 466 00:22:58,140 --> 00:23:01,170 So first obviously, we need to start off 467 00:23:01,170 --> 00:23:03,510 with getting the data into Hashcat. 468 00:23:03,510 --> 00:23:06,690 So my Python tooling can extract the portion 469 00:23:06,690 --> 00:23:09,540 of the media variables file that's kind of the header, 470 00:23:09,540 --> 00:23:14,310 so we can confirm that the encryption is what we expect 471 00:23:14,310 --> 00:23:16,110 because we can check certain bites in the header 472 00:23:16,110 --> 00:23:19,080 to make sure that it matches what what we're looking for. 473 00:23:19,080 --> 00:23:22,440 And then the last portion of this string 474 00:23:22,440 --> 00:23:25,530 is effectively some of the encrypted data. 475 00:23:25,530 --> 00:23:29,550 To jump a little bit forward, the media variables file 476 00:23:29,550 --> 00:23:31,770 is effectively just an XML document. 477 00:23:31,770 --> 00:23:35,880 So we actually know the beginning of the string, 478 00:23:35,880 --> 00:23:37,740 it's always going to be constant. 479 00:23:37,740 --> 00:23:39,930 So because we have known plain text, 480 00:23:39,930 --> 00:23:42,063 when we are developing a Hashcat module, 481 00:23:43,590 --> 00:23:45,330 we can treat it as a hash 482 00:23:45,330 --> 00:23:48,630 because we can take our key that we derive, 483 00:23:48,630 --> 00:23:51,810 encrypt it, and then compare that encrypted value 484 00:23:51,810 --> 00:23:56,070 to the known value here, and if that matches, 485 00:23:56,070 --> 00:23:58,500 it means that the key that was derived 486 00:23:58,500 --> 00:24:01,400 was from the same password, so we figure out the password. 487 00:24:02,250 --> 00:24:04,470 Okay, so we have this data, 488 00:24:04,470 --> 00:24:06,420 and we need to feed it into Hashcat. 489 00:24:06,420 --> 00:24:08,943 So I just write it to a file, 490 00:24:10,170 --> 00:24:12,510 and then I start running Hashcat. 491 00:24:12,510 --> 00:24:13,343 I'm gonna skip ahead 492 00:24:13,343 --> 00:24:16,140 because it takes a while to initialize. 493 00:24:16,140 --> 00:24:18,963 But when it actually starts running the attack, 494 00:24:19,980 --> 00:24:21,120 what I've done here is 495 00:24:21,120 --> 00:24:23,790 I've run my Hashcat module using Roku, 496 00:24:23,790 --> 00:24:24,900 it doesn't really matter, 497 00:24:24,900 --> 00:24:28,650 the module supports all kinds of cracking options. 498 00:24:28,650 --> 00:24:31,980 You can crack with rules, you can crack with dictionaries, 499 00:24:31,980 --> 00:24:35,343 you can do a brute-force attack, all of that kind of works. 500 00:24:36,900 --> 00:24:39,240 Sorry, I didn't want to do that, 501 00:24:39,240 --> 00:24:44,240 let me skip forward again, sorry, okay. 502 00:24:44,640 --> 00:24:46,653 So struggling with PowerPoint media. 503 00:24:48,180 --> 00:24:53,113 Okay, so yes, we can run through Roku.txt 504 00:24:54,060 --> 00:24:56,670 with the known password at the end of the file, 505 00:24:56,670 --> 00:24:58,380 it cracks successfully. 506 00:24:58,380 --> 00:25:01,560 If we do a benchmark of the same Hashcat module, 507 00:25:01,560 --> 00:25:03,000 we can see that this is running 508 00:25:03,000 --> 00:25:05,673 at about three giga hashes a second. 509 00:25:07,290 --> 00:25:08,760 It's not the fastest thing in the world, 510 00:25:08,760 --> 00:25:11,880 it's definitely not cracking at the rate of an NT-hash, 511 00:25:11,880 --> 00:25:15,090 it's not MD4, but it is still pretty fast. 512 00:25:15,090 --> 00:25:19,410 It's about 50% faster than cracking an NTLM challenge, 513 00:25:19,410 --> 00:25:21,780 NTLMv2 challenge/response. 514 00:25:21,780 --> 00:25:24,450 So if it's a weak password, it's probably gonna fall, 515 00:25:24,450 --> 00:25:28,923 and you can actually crack using dictionaries pretty fast. 516 00:25:31,080 --> 00:25:33,870 How did I figure out how all of this works? 517 00:25:33,870 --> 00:25:35,820 Well, there's one thing to note, 518 00:25:35,820 --> 00:25:39,210 which is SCCM is probably one of the most logged pieces 519 00:25:39,210 --> 00:25:41,310 of software in the world. 520 00:25:41,310 --> 00:25:44,223 So both on the server side and on the client side, 521 00:25:45,060 --> 00:25:47,010 everything that each of those pieces 522 00:25:47,010 --> 00:25:49,350 of software is doing is being logged. 523 00:25:49,350 --> 00:25:52,890 If we dig around the WinPE Environment 524 00:25:52,890 --> 00:25:56,670 inside C Windows, Temp, SMSTs log, 525 00:25:56,670 --> 00:25:59,820 we find a text file that contains the log 526 00:25:59,820 --> 00:26:02,340 of what the client is trying to do. 527 00:26:02,340 --> 00:26:07,340 Looking through that at some point, there's a entry called 528 00:26:07,350 --> 00:26:12,150 loading media variables from X SMS, data variables.dat, 529 00:26:12,150 --> 00:26:13,860 which is exactly what we're looking for. 530 00:26:13,860 --> 00:26:15,840 We know that it's trying to decrypt that, 531 00:26:15,840 --> 00:26:20,460 and exactly after that, it logs a call to crypt decrypt. 532 00:26:20,460 --> 00:26:24,390 So crypt decrypt is a function in the Windows CryptoAPI 533 00:26:24,390 --> 00:26:29,390 that is used in order to, yeah, attempt to decrypt the file. 534 00:26:30,540 --> 00:26:32,927 So we know that it's using Windows crypto (laughs), 535 00:26:34,320 --> 00:26:36,060 it's using CryptoAPI 536 00:26:36,060 --> 00:26:38,580 in order to attempt to decrypt this file. 537 00:26:38,580 --> 00:26:40,950 Now, because we have the shell, 538 00:26:40,950 --> 00:26:43,320 we can actually inject custom software 539 00:26:43,320 --> 00:26:45,630 inside the WinPE Environment. 540 00:26:45,630 --> 00:26:49,980 So I used x64dbg loaded it on a random CD, 541 00:26:49,980 --> 00:26:53,520 the CD drive is accessible within the WinPE Environment. 542 00:26:53,520 --> 00:26:55,680 So we can actually run x64dbg, 543 00:26:55,680 --> 00:26:59,580 and since we know that we're running TsmBootstrap.exe, 544 00:26:59,580 --> 00:27:02,070 we debug TsmBootstrap.exe, 545 00:27:02,070 --> 00:27:04,713 and we can search for all intermodular calls. 546 00:27:05,640 --> 00:27:07,080 Here highlighted in red 547 00:27:07,080 --> 00:27:09,870 is effectively a series of intermodular calls, 548 00:27:09,870 --> 00:27:12,210 where it seems to be setting up 549 00:27:12,210 --> 00:27:14,220 and initializing the crypto functions, 550 00:27:14,220 --> 00:27:16,440 then calling them deriving a key, 551 00:27:16,440 --> 00:27:18,120 and destroying what it's initialized. 552 00:27:18,120 --> 00:27:20,620 So that looks like roughly what we're looking for. 553 00:27:23,130 --> 00:27:24,690 So how does it work? 554 00:27:24,690 --> 00:27:28,080 Well, if we actually debug these individual calls 555 00:27:28,080 --> 00:27:30,090 to try and identify what's going on, 556 00:27:30,090 --> 00:27:32,073 one thing that we'll notice is that 557 00:27:32,073 --> 00:27:35,190 when CryptCreateHash is called, 558 00:27:35,190 --> 00:27:38,070 the second function, the second parameter 559 00:27:38,070 --> 00:27:42,060 that is passed to it is the hex value, 8004. 560 00:27:42,060 --> 00:27:46,410 If we look at the function definition CryptCreateHash 561 00:27:46,410 --> 00:27:48,030 in the Windows documentation, 562 00:27:48,030 --> 00:27:51,120 the second argument is an algorithm identifier, 563 00:27:51,120 --> 00:27:55,020 and 8004 corresponds to a SHA-1 hash. 564 00:27:55,020 --> 00:28:00,020 So we are creating a SHA-1 hash of the actual password 565 00:28:00,840 --> 00:28:01,980 that we're passing in. 566 00:28:01,980 --> 00:28:04,560 So the argument to CryptCreateHash 567 00:28:04,560 --> 00:28:06,990 is the password that we typed into that box. 568 00:28:06,990 --> 00:28:11,223 In this case, I typed A, so we see A as, 569 00:28:11,223 --> 00:28:14,160 the there's a pointer to a string value. 570 00:28:14,160 --> 00:28:17,100 So we are hashing A with SHA-1, 571 00:28:17,100 --> 00:28:22,100 and then we are calling CryptDeriveKey using that hash. 572 00:28:22,230 --> 00:28:26,040 The second argument to CryptDeriveKey here is 66OE. 573 00:28:28,080 --> 00:28:31,650 The Windows API functions are actually pretty consistent, 574 00:28:31,650 --> 00:28:34,620 so it turns out that CryptDeriveKey, 575 00:28:34,620 --> 00:28:37,530 the second argument is also an algorithm identifier. 576 00:28:37,530 --> 00:28:40,323 And if we go look up that algorithm identifier, 577 00:28:41,865 --> 00:28:43,800 it is telling us that we're deriving a key 578 00:28:43,800 --> 00:28:48,800 for an AES-128 encrypted value. 579 00:28:50,730 --> 00:28:55,230 Okay, so we have an idea of what it's doing, 580 00:28:55,230 --> 00:28:57,780 but we don't really know what CryptDeriveKey does 581 00:28:57,780 --> 00:28:59,313 in order to get its key. 582 00:29:00,330 --> 00:29:03,000 Turns out if you just scroll down in the documentation, 583 00:29:03,000 --> 00:29:05,100 Microsoft was kind enough to actually document 584 00:29:05,100 --> 00:29:08,610 exactly how the key derivation works. 585 00:29:08,610 --> 00:29:12,810 So we take our shell and hash, do a bunch of stuff to it, 586 00:29:12,810 --> 00:29:15,363 and then we get an AES-128 key out. 587 00:29:16,200 --> 00:29:18,570 What the Hashcat module involved doing, 588 00:29:18,570 --> 00:29:21,210 was re-implementing this in OpenCL. 589 00:29:21,210 --> 00:29:22,980 Hashcat is great, 590 00:29:22,980 --> 00:29:27,300 it has some really nice standard cryptographic functions 591 00:29:27,300 --> 00:29:29,700 built into the libraries that it provides. 592 00:29:29,700 --> 00:29:33,390 So we can actually use all of those standard libraries 593 00:29:33,390 --> 00:29:35,340 in order to perform the same actions 594 00:29:35,340 --> 00:29:37,080 that are documented here. 595 00:29:37,080 --> 00:29:39,450 And then at the end, we'll get a key that again, 596 00:29:39,450 --> 00:29:41,070 we can encrypt a known value, 597 00:29:41,070 --> 00:29:44,220 compare that to the data that we provided in. 598 00:29:44,220 --> 00:29:45,420 And if it matches, 599 00:29:45,420 --> 00:29:47,910 then we know that we've guessed the password. 600 00:29:47,910 --> 00:29:49,830 If we've guessed the password, we've guessed the key, 601 00:29:49,830 --> 00:29:53,583 which means that we can decrypt our variables.dat file, 602 00:29:53,583 --> 00:29:57,690 that we were going for in the, yeah, that we were going for. 603 00:29:57,690 --> 00:30:00,420 So which are the important variables 604 00:30:00,420 --> 00:30:01,890 that we wanna pull out of this? 605 00:30:01,890 --> 00:30:04,860 Well, they're highlighted in red. 606 00:30:04,860 --> 00:30:09,390 The most important is not the one that's highlighted there, 607 00:30:09,390 --> 00:30:12,690 it's SMSTS media PFX, 608 00:30:12,690 --> 00:30:16,440 which is a public private key pair 609 00:30:16,440 --> 00:30:20,550 that is effectively the certificate that the client uses 610 00:30:20,550 --> 00:30:23,460 to authenticate itself to the management point 611 00:30:23,460 --> 00:30:26,130 in order to pull down policies 612 00:30:26,130 --> 00:30:31,020 that PFX, as most PFX's are, is password-protected. 613 00:30:31,020 --> 00:30:34,350 There is a value called SMSmedia GUID. 614 00:30:34,350 --> 00:30:39,350 Let me actually just highlight this, laser pointer. 615 00:30:39,390 --> 00:30:41,500 Okay, so I think you can see that. 616 00:30:41,500 --> 00:30:43,890 Yeah, so SMS media GUID 617 00:30:43,890 --> 00:30:48,410 which is a string value that is used to encrypt this PFX. 618 00:30:48,410 --> 00:30:51,210 So the first 31 characters of the media GUID 619 00:30:51,210 --> 00:30:53,250 is used to encrypt the PFX. 620 00:30:53,250 --> 00:30:57,630 And then lastly, there is a value called SMSTSMP 621 00:30:57,630 --> 00:30:59,670 that points at the media, sorry, 622 00:30:59,670 --> 00:31:01,680 the management point that we need to talk to 623 00:31:01,680 --> 00:31:03,450 in order to pull down the policies. 624 00:31:03,450 --> 00:31:04,680 So we have, at this point, 625 00:31:04,680 --> 00:31:06,120 all of the information that we need 626 00:31:06,120 --> 00:31:09,300 to actually successfully start communication with SCCM, 627 00:31:09,300 --> 00:31:10,890 because we have the certificate, 628 00:31:10,890 --> 00:31:12,810 we have the server we need to talk to, 629 00:31:12,810 --> 00:31:15,060 and we have the password for the certificate. 630 00:31:16,290 --> 00:31:20,553 Okay, so how does client comms work? 631 00:31:22,500 --> 00:31:27,500 Well, let's go back to our password screen 632 00:31:29,250 --> 00:31:31,080 that we started off with. 633 00:31:31,080 --> 00:31:33,360 One good way to figure out what's going on here 634 00:31:33,360 --> 00:31:36,000 is to actually start using wireshark, 635 00:31:36,000 --> 00:31:38,730 to monitor the HTTP traffic that's passed 636 00:31:38,730 --> 00:31:42,570 between our Configuration Manager client and the server, 637 00:31:42,570 --> 00:31:45,060 so we type in the known password. 638 00:31:45,060 --> 00:31:48,720 What we see then is this HTTP request, 639 00:31:48,720 --> 00:31:52,450 this is a CCM post to CCM system request 640 00:31:53,730 --> 00:31:57,330 with a request assignment's XML message, 641 00:31:57,330 --> 00:31:59,820 this request assignment's XML message 642 00:31:59,820 --> 00:32:02,077 is effectively the client asking for, 643 00:32:02,077 --> 00:32:04,477 "Hey, I'm a Configuration Manager client, 644 00:32:04,477 --> 00:32:07,680 "please tell me what policies I need to install." 645 00:32:07,680 --> 00:32:09,810 This request is actually authenticated 646 00:32:09,810 --> 00:32:11,490 by a bunch of signatures. 647 00:32:11,490 --> 00:32:13,860 We see client token signature, 648 00:32:13,860 --> 00:32:16,290 we see CCM client ID signature, 649 00:32:16,290 --> 00:32:19,920 and we see CCM client timestamp signature. 650 00:32:19,920 --> 00:32:22,800 All of these, if they are provided, are kind of verified 651 00:32:22,800 --> 00:32:25,683 by the SCCM server to make sure that they check out. 652 00:32:26,850 --> 00:32:29,550 Okay, so assuming that all works, 653 00:32:29,550 --> 00:32:32,640 we will receive from the SCCM server 654 00:32:32,640 --> 00:32:35,460 a reply assignment XML document, 655 00:32:35,460 --> 00:32:39,990 and that contains a bunch of policies with some URLs 656 00:32:39,990 --> 00:32:43,090 that point to where we can download the policies 657 00:32:45,270 --> 00:32:48,600 that our SCCM client should apply. 658 00:32:48,600 --> 00:32:50,490 Now, we already discussed this, 659 00:32:50,490 --> 00:32:51,810 there's actually three policies 660 00:32:51,810 --> 00:32:53,550 that we're specifically interested in 661 00:32:53,550 --> 00:32:55,740 because we know that they result in passwords 662 00:32:55,740 --> 00:32:57,330 ending up in our client, 663 00:32:57,330 --> 00:33:00,360 task sequences, Network Access Account config, 664 00:33:00,360 --> 00:33:01,410 and collection settings. 665 00:33:01,410 --> 00:33:04,710 So we can filter our reply assignments XML document 666 00:33:04,710 --> 00:33:07,590 to kind of figure out these are the sensitive policies 667 00:33:07,590 --> 00:33:10,500 that we're interested in, let's go download those. 668 00:33:10,500 --> 00:33:13,230 And if we actually download one of them, 669 00:33:13,230 --> 00:33:14,730 we again need to authenticate. 670 00:33:14,730 --> 00:33:16,140 There's some signatures here, 671 00:33:16,140 --> 00:33:19,420 but the data that we received back is an encrypted blob 672 00:33:22,710 --> 00:33:26,133 that is encrypted using the certificate 673 00:33:26,133 --> 00:33:27,693 that we already have. 674 00:33:28,920 --> 00:33:32,670 Okay, so we have a high-level picture of how it works, 675 00:33:32,670 --> 00:33:35,010 how can we use it to pull out passwords? 676 00:33:35,010 --> 00:33:38,130 Well, like this. 677 00:33:38,130 --> 00:33:42,330 So because we have our media variables file, 678 00:33:42,330 --> 00:33:44,610 we can take our media variables file, 679 00:33:44,610 --> 00:33:46,470 take the password that we cracked 680 00:33:46,470 --> 00:33:48,990 and provide it to PXE Thief. 681 00:33:48,990 --> 00:33:53,070 It's able to then issue requests to the, 682 00:33:53,070 --> 00:33:56,400 well, generate the signatures that we need to authenticate, 683 00:33:56,400 --> 00:34:00,840 issue requests to SCCM to pull first the assignments 684 00:34:00,840 --> 00:34:04,740 that it needs to apply, and then the policies, 685 00:34:04,740 --> 00:34:07,590 the specific policies that we're interested in. 686 00:34:07,590 --> 00:34:10,953 And then after it receives those policies, 687 00:34:12,570 --> 00:34:14,220 sorry, let me just skip forward. 688 00:34:14,220 --> 00:34:16,470 It is then able to take those policies 689 00:34:16,470 --> 00:34:19,290 and decrypt them in order to get the clear text passwords 690 00:34:19,290 --> 00:34:21,483 that are stored within those policies. 691 00:34:22,530 --> 00:34:24,780 Okay, so the key bit to understand here 692 00:34:24,780 --> 00:34:26,130 is how does the signature work, 693 00:34:26,130 --> 00:34:28,020 because that's really the thing that's stopping us 694 00:34:28,020 --> 00:34:31,470 from doing this just out of hand. 695 00:34:31,470 --> 00:34:34,740 Turns out that if we go using x64dbg, 696 00:34:34,740 --> 00:34:37,170 if we go on an active debugging spree, 697 00:34:37,170 --> 00:34:40,740 we can see that CryptSignHash from CryptoAPI 698 00:34:40,740 --> 00:34:44,280 is used to generate these hashes, these signatures. 699 00:34:44,280 --> 00:34:46,590 So we have some kind of known value, 700 00:34:46,590 --> 00:34:49,440 like for example, let's take CCM client ID, 701 00:34:49,440 --> 00:34:53,670 it's provided to us in the media variables. 702 00:34:53,670 --> 00:34:57,330 We take that value, we sign it using the PFX value, 703 00:34:57,330 --> 00:34:59,970 we provide both of them to the SCCM server. 704 00:34:59,970 --> 00:35:02,550 And because it also has a copy of the certificate, 705 00:35:02,550 --> 00:35:05,163 it can verify that this signature is legitimate. 706 00:35:06,330 --> 00:35:08,520 Okay, so that's how we authenticate. 707 00:35:08,520 --> 00:35:11,640 Now, how do we decrypt these encrypted policies? 708 00:35:11,640 --> 00:35:15,120 Well, again, if we go on an active debugging spree, 709 00:35:15,120 --> 00:35:20,100 we figure out that the, yeah, 710 00:35:20,100 --> 00:35:24,330 that binary blob is encrypted using crypt, encrypt message, 711 00:35:24,330 --> 00:35:25,230 which we can decrypt 712 00:35:25,230 --> 00:35:27,753 with CrypDecry message using the certificate. 713 00:35:29,100 --> 00:35:32,710 That leaves us with a plain text policy XML 714 00:35:33,780 --> 00:35:38,340 that will be dependent on the specific policies 715 00:35:38,340 --> 00:35:39,540 that we're looking at. 716 00:35:39,540 --> 00:35:42,270 Most of these will just be clear text at this point, 717 00:35:42,270 --> 00:35:44,760 but if they can contain passwords, 718 00:35:44,760 --> 00:35:47,910 SCCM isn't done with the encryption yet. 719 00:35:47,910 --> 00:35:50,940 So in this case, I've highlighted the value here, 720 00:35:50,940 --> 00:35:55,410 TS_sequence it's marked as secret. 721 00:35:55,410 --> 00:35:57,630 And that means that they've implemented 722 00:35:57,630 --> 00:35:58,860 some kind of obfuscation 723 00:35:58,860 --> 00:36:01,890 to make sure that we can't just read it outright. 724 00:36:01,890 --> 00:36:06,870 It starts off with the Hex value, 89130000, 725 00:36:06,870 --> 00:36:08,220 which will be relevant later on, 726 00:36:08,220 --> 00:36:10,380 which is why I'm telling you now. 727 00:36:10,380 --> 00:36:12,270 But effectively again, 728 00:36:12,270 --> 00:36:14,100 if we go in this active debugging spree, 729 00:36:14,100 --> 00:36:17,010 we'll figure out that the string 730 00:36:17,010 --> 00:36:18,930 is actually just tripled DES encrypted 731 00:36:18,930 --> 00:36:21,750 with a key that's inside that hex string. 732 00:36:21,750 --> 00:36:24,660 So we can pull the key, decrypt the value, 733 00:36:24,660 --> 00:36:27,270 and get the clear test task sequence. 734 00:36:27,270 --> 00:36:29,130 Once we have the clear test task sequence, 735 00:36:29,130 --> 00:36:31,590 things start to make a lot more sense. 736 00:36:31,590 --> 00:36:34,110 If we look in the Configuration Manager console, 737 00:36:34,110 --> 00:36:36,660 there's a bunch of steps in each task sequence 738 00:36:36,660 --> 00:36:39,750 for the steps that can contain passwords, 739 00:36:39,750 --> 00:36:43,140 we actually just get the straight care text passwords here. 740 00:36:43,140 --> 00:36:45,030 So in this case, I've highlighted 741 00:36:45,030 --> 00:36:47,730 the domain-joining credentials that are associated 742 00:36:47,730 --> 00:36:51,663 with the applying network settings task sequence step. 743 00:36:53,550 --> 00:36:56,880 Okay, now, the interesting thing is that 744 00:36:56,880 --> 00:37:00,420 I've discussed how to do this when a password is required, 745 00:37:00,420 --> 00:37:02,940 but you don't necessarily need a password. 746 00:37:02,940 --> 00:37:07,650 So if we look at the specific place in SCCM, 747 00:37:07,650 --> 00:37:10,920 in the SCCM console where you set up PXE, 748 00:37:10,920 --> 00:37:14,070 you can untick the box that says require password. 749 00:37:14,070 --> 00:37:15,903 So when you boot into it, 750 00:37:17,346 --> 00:37:19,380 the Configuration Manager client just tells you, 751 00:37:19,380 --> 00:37:22,323 this media is not password protected, click next. 752 00:37:23,250 --> 00:37:24,660 How does that work? 753 00:37:24,660 --> 00:37:27,930 Well, if you encounter an environment that has this setup, 754 00:37:27,930 --> 00:37:30,240 we can actually just go from the first step 755 00:37:30,240 --> 00:37:31,950 all the way to decrypting variables. 756 00:37:31,950 --> 00:37:34,050 Because there's no password to protect it, 757 00:37:36,180 --> 00:37:38,640 we can pull the key, I'll explain how, 758 00:37:38,640 --> 00:37:40,440 and then we can just immediately decrypt it 759 00:37:40,440 --> 00:37:42,990 and get clear text, creates out. 760 00:37:42,990 --> 00:37:47,850 Now, the secret here is essentially in that response 761 00:37:47,850 --> 00:37:50,310 to the specific DHCP message that, 762 00:37:50,310 --> 00:37:52,290 we send to the SCCM server. 763 00:37:52,290 --> 00:37:53,700 I already said, there's a portion 764 00:37:53,700 --> 00:37:55,170 that starts with 01 765 00:37:55,170 --> 00:37:58,083 that points us at our encrypted media variable file. 766 00:37:59,070 --> 00:38:01,140 The media variable (chuckles) 767 00:38:01,140 --> 00:38:03,810 media variable file is still encrypted 768 00:38:03,810 --> 00:38:06,660 in the case where we don't require a password. 769 00:38:06,660 --> 00:38:11,660 But the key is actually sent as part of DHCP option 243 770 00:38:12,360 --> 00:38:14,997 in a portion that starts with 02. 771 00:38:14,997 --> 00:38:19,290 So 02 a length field, and then we have an encrypted key. 772 00:38:19,290 --> 00:38:21,840 Now, SCCM at least encrypts it 773 00:38:21,840 --> 00:38:24,450 because it realizes this is being sent over the network, 774 00:38:24,450 --> 00:38:27,090 so we don't want to expose the media variables file 775 00:38:27,090 --> 00:38:28,500 straight off the bat, 776 00:38:28,500 --> 00:38:30,660 but we can't really do much 777 00:38:30,660 --> 00:38:33,480 to prevent this from being decrypted 778 00:38:33,480 --> 00:38:36,330 because the client still needs, at some point, 779 00:38:36,330 --> 00:38:39,600 to access it, and there's no real secret involved here. 780 00:38:39,600 --> 00:38:43,260 So it turns out that there's another layer of obfuscation, 781 00:38:43,260 --> 00:38:45,660 and going on an active debugging street, 782 00:38:45,660 --> 00:38:46,950 we can find a function 783 00:38:46,950 --> 00:38:50,763 called extract password inside TS.PXE.dll. 784 00:38:52,290 --> 00:38:53,700 Inside that function, 785 00:38:53,700 --> 00:38:56,130 there is a call to decrypt buffer 786 00:38:56,130 --> 00:39:01,130 that references a hard coded key inside the same file, 787 00:39:01,410 --> 00:39:05,700 and then refers to this DHCP option portion 788 00:39:05,700 --> 00:39:07,140 that we just discussed. 789 00:39:07,140 --> 00:39:09,930 So it turns out that this is encrypted 790 00:39:09,930 --> 00:39:12,240 using the hard coded key there. 791 00:39:12,240 --> 00:39:17,240 So what we do is we take the DHCP option 243, 792 00:39:18,030 --> 00:39:20,220 pass out that second option, 793 00:39:20,220 --> 00:39:23,400 decrypt it using the hard coded key, 794 00:39:23,400 --> 00:39:25,020 and then we have a random key 795 00:39:25,020 --> 00:39:28,020 that is used to encrypt our media variables file, 796 00:39:28,020 --> 00:39:31,200 but because it's being sent in that DHCP response, 797 00:39:31,200 --> 00:39:33,480 this is easy to do straight off the bat 798 00:39:33,480 --> 00:39:35,730 once you know what's happening. 799 00:39:35,730 --> 00:39:38,400 Okay, so now we've run through everything 800 00:39:38,400 --> 00:39:40,470 that can happen with network booting, 801 00:39:40,470 --> 00:39:42,810 but if you remember in the beginning, 802 00:39:42,810 --> 00:39:44,790 OSD isn't just network booting, 803 00:39:44,790 --> 00:39:48,330 it does include media files that we can use 804 00:39:48,330 --> 00:39:51,570 in order to initiate operating system deployment. 805 00:39:51,570 --> 00:39:52,860 How does that work? 806 00:39:52,860 --> 00:39:57,060 So inside the Configuration Manager console, 807 00:39:57,060 --> 00:39:59,550 you can take a task sequence 808 00:39:59,550 --> 00:40:03,810 and generate a media file that is used 809 00:40:03,810 --> 00:40:06,270 to initiate this OSD method. 810 00:40:06,270 --> 00:40:08,940 There's three main types, standalone media, 811 00:40:08,940 --> 00:40:11,280 bootable media, and pre-stage media. 812 00:40:11,280 --> 00:40:13,740 Pre-stage media is a file that we can ship off 813 00:40:13,740 --> 00:40:18,740 to a laptop manufacturer so that when the laptop comes up, 814 00:40:18,750 --> 00:40:22,410 it will attempt to contact our specific SCCM server 815 00:40:22,410 --> 00:40:23,973 and complete the installation. 816 00:40:24,990 --> 00:40:28,350 Bootable media is effectively an ISO file or a USB 817 00:40:28,350 --> 00:40:31,320 that will just boot into a WinPE Environment 818 00:40:31,320 --> 00:40:33,570 and start a client like we've seen already. 819 00:40:33,570 --> 00:40:36,690 And standalone media is probably the most interesting one 820 00:40:36,690 --> 00:40:38,160 where it is designed 821 00:40:38,160 --> 00:40:41,340 to not use network communications at all, 822 00:40:41,340 --> 00:40:44,460 but still complete an operating system deployment. 823 00:40:44,460 --> 00:40:47,010 So it needs to package all of the software 824 00:40:47,010 --> 00:40:51,450 and all of the policy settings onto that ISO file 825 00:40:51,450 --> 00:40:54,093 in order to be able to do it completely offline. 826 00:40:55,050 --> 00:40:57,450 If we look at the contents of these files, 827 00:40:57,450 --> 00:40:59,823 so I went and I generated one of each. 828 00:41:00,690 --> 00:41:01,590 If we look at it, 829 00:41:01,590 --> 00:41:05,160 we actually see a lot of similarities with our Ram disk 830 00:41:05,160 --> 00:41:07,533 that's sitting inside WinPE. 831 00:41:08,400 --> 00:41:11,490 So there is an SMS folder, 832 00:41:11,490 --> 00:41:14,460 inside that SMS folder there's a data folder. 833 00:41:14,460 --> 00:41:19,460 And for both the bootable media and the pre-stage media, 834 00:41:19,740 --> 00:41:22,170 there is just a variables.dat file 835 00:41:22,170 --> 00:41:23,790 and then a configuration file, 836 00:41:23,790 --> 00:41:27,360 our TsmBootstrap.ini that's just telling us 837 00:41:27,360 --> 00:41:30,660 how to run the client in the first place. 838 00:41:30,660 --> 00:41:32,370 If we look at the standalone media, 839 00:41:32,370 --> 00:41:35,640 there is also an additional file called Policy.XML 840 00:41:35,640 --> 00:41:37,440 that contains all of the policies 841 00:41:37,440 --> 00:41:39,090 that this media needs to apply 842 00:41:39,090 --> 00:41:41,463 in order to successfully deploy the laptop. 843 00:41:42,690 --> 00:41:46,800 Okay, so how do we turn this into creds? 844 00:41:46,800 --> 00:41:51,240 So I'm going to talk about standalone media primarily, 845 00:41:51,240 --> 00:41:53,910 because that's the interesting one that has the new file. 846 00:41:53,910 --> 00:41:57,630 It turns out that both bootable media and pre-stage media 847 00:41:57,630 --> 00:42:02,403 have a certificate inside their variables.dat file. 848 00:42:03,540 --> 00:42:06,780 And we can use that certificate 849 00:42:06,780 --> 00:42:08,220 to perform the exact same attack 850 00:42:08,220 --> 00:42:11,670 as we would once we obtain that certificate 851 00:42:11,670 --> 00:42:13,083 from a PXE perspective. 852 00:42:14,040 --> 00:42:19,040 Okay, so in the case of a standalone media file, 853 00:42:20,760 --> 00:42:23,790 we can take, if we know the password, 854 00:42:23,790 --> 00:42:26,730 again, we can perform cracking if we need to, 855 00:42:26,730 --> 00:42:29,520 because the variables.dat file for media file 856 00:42:29,520 --> 00:42:31,440 is generated in the exact same way 857 00:42:31,440 --> 00:42:33,360 as it would be for a PXE file. 858 00:42:33,360 --> 00:42:36,900 We can generate, once we know the password, 859 00:42:36,900 --> 00:42:39,270 we can provide the password to PXE thief. 860 00:42:39,270 --> 00:42:43,380 It can derive the key and decrypt both the policy 861 00:42:43,380 --> 00:42:45,633 and variables.dat files. 862 00:42:46,590 --> 00:42:49,080 And then we are, because all of the policies 863 00:42:49,080 --> 00:42:51,330 are sitting inside that Policy.XML file, 864 00:42:51,330 --> 00:42:53,130 it works exactly the same 865 00:42:53,130 --> 00:42:55,833 as if we were operating in a PXE environment. 866 00:42:56,730 --> 00:42:59,490 Again, with our media files, 867 00:42:59,490 --> 00:43:01,740 we can also choose to not set a password. 868 00:43:01,740 --> 00:43:04,623 If we don't set a password, there's just a static string. 869 00:43:05,550 --> 00:43:08,520 So we can take the static string, derive a key from it, 870 00:43:08,520 --> 00:43:12,300 use that to decrypt the policy and the media variables file, 871 00:43:12,300 --> 00:43:14,190 and then we are off to the races, 872 00:43:14,190 --> 00:43:18,090 we can decrypt our policies. 873 00:43:18,090 --> 00:43:20,070 Now, the important thing to note, 874 00:43:20,070 --> 00:43:23,100 actually for standalone media is 875 00:43:23,100 --> 00:43:26,790 unlike when a password is set, 876 00:43:26,790 --> 00:43:29,340 there's a different key that is used 877 00:43:29,340 --> 00:43:32,373 for the Policy.XML and for the variables.dat. 878 00:43:34,230 --> 00:43:37,500 We always use the password to decrypt variables.dat, 879 00:43:37,500 --> 00:43:40,800 but in the case of a standalone media 880 00:43:40,800 --> 00:43:42,030 that doesn't have a password, 881 00:43:42,030 --> 00:43:46,050 we take the SMS media GUID from that variables.dat file 882 00:43:46,050 --> 00:43:47,520 and use that to derive a new key 883 00:43:47,520 --> 00:43:51,060 that's used to encrypt the policy file. 884 00:43:51,060 --> 00:43:54,030 Okay, so at a high level, 885 00:43:54,030 --> 00:43:56,610 bootable media, pre-stage media, we get a certificate, 886 00:43:56,610 --> 00:44:00,900 we use the certificate, pull policies, get creds. 887 00:44:00,900 --> 00:44:02,730 If we are on a standalone media, 888 00:44:02,730 --> 00:44:05,913 we have to decrypt that Policy.XML file somehow. 889 00:44:06,750 --> 00:44:09,660 How do we turn this into a realistic attack? 890 00:44:09,660 --> 00:44:12,270 Well, if we're sitting in an environment 891 00:44:12,270 --> 00:44:14,130 where we can do a PXE boot, 892 00:44:14,130 --> 00:44:17,178 what we need to do is we need to prompt for PXE boot, 893 00:44:17,178 --> 00:44:19,200 find out where the SCCM survey is, 894 00:44:19,200 --> 00:44:21,570 get our hands on that media variables file. 895 00:44:21,570 --> 00:44:23,490 And once we have the media variables file, 896 00:44:23,490 --> 00:44:25,530 crack the password if there is a password, 897 00:44:25,530 --> 00:44:29,820 or use the key that was sent to us to decrypt it. 898 00:44:29,820 --> 00:44:31,260 If we crack the password, 899 00:44:31,260 --> 00:44:34,740 we can then use the certificate and get all the creds. 900 00:44:34,740 --> 00:44:37,380 If we have low privileged domain credentials, 901 00:44:37,380 --> 00:44:39,900 we have a number of other options available to us. 902 00:44:39,900 --> 00:44:43,350 We can actually, I showed you the folder, 903 00:44:43,350 --> 00:44:45,300 Ram Installed SMS Temp, 904 00:44:45,300 --> 00:44:49,200 that in general is actually a share on the SCCM server 905 00:44:49,200 --> 00:44:51,210 that all domain users can read. 906 00:44:51,210 --> 00:44:52,890 So even if you're not in the position 907 00:44:52,890 --> 00:44:56,070 to prompt the SCCM server for a PXE boot, 908 00:44:56,070 --> 00:44:57,420 you can use credentials 909 00:44:57,420 --> 00:44:59,640 to go look at the contents of SMS Temp. 910 00:44:59,640 --> 00:45:01,950 And if there's a variables file in there, 911 00:45:01,950 --> 00:45:04,500 you can download that file and attempt to crack it. 912 00:45:06,780 --> 00:45:08,160 On the other side of things, 913 00:45:08,160 --> 00:45:10,950 obviously, these media files are files 914 00:45:10,950 --> 00:45:13,080 that are lying around somewhere on the network. 915 00:45:13,080 --> 00:45:15,090 If we can find those files, 916 00:45:15,090 --> 00:45:19,560 we can attempt to, again, crack, if there's a password set. 917 00:45:19,560 --> 00:45:20,820 If there isn't the password set, 918 00:45:20,820 --> 00:45:23,280 we just use the default string and cool. 919 00:45:23,280 --> 00:45:24,240 We have the certificate, 920 00:45:24,240 --> 00:45:26,820 or we have the decrypted policy 921 00:45:26,820 --> 00:45:29,670 that gives us the credentials that we want. 922 00:45:29,670 --> 00:45:33,540 Okay, is there any post-exploitation potential with this? 923 00:45:33,540 --> 00:45:35,550 Turns out that there is. 924 00:45:35,550 --> 00:45:38,403 If we have administrative access over the SMS, 925 00:45:39,240 --> 00:45:40,073 SMS server (chuckles), 926 00:45:40,073 --> 00:45:41,940 the SCCM server, 927 00:45:41,940 --> 00:45:45,210 we can actually ask for specific registry keys. 928 00:45:45,210 --> 00:45:47,190 And the certificate that we're looking for 929 00:45:47,190 --> 00:45:49,170 is actually just stored as a registry key 930 00:45:49,170 --> 00:45:50,570 that we can access remotely. 931 00:45:51,540 --> 00:45:53,700 So we can pull the identity.Guid, 932 00:45:53,700 --> 00:45:55,890 which again is used to encrypt the certificate. 933 00:45:55,890 --> 00:45:58,860 We can pull the certificate bite, 934 00:45:58,860 --> 00:46:02,190 try and import it, use the password to decrypt it. 935 00:46:02,190 --> 00:46:03,960 And cool, we have the cert that we need 936 00:46:03,960 --> 00:46:07,650 in order to persistently be able to do this 937 00:46:07,650 --> 00:46:09,000 going into the future. 938 00:46:09,000 --> 00:46:12,960 Now, the reason this is useful for post-exploitation 939 00:46:12,960 --> 00:46:13,980 is because it's actually 940 00:46:13,980 --> 00:46:16,380 a really nice persistence technique. 941 00:46:16,380 --> 00:46:19,050 If credentials are stored within task sequences, 942 00:46:19,050 --> 00:46:22,080 the Network Access Account collection variables, 943 00:46:22,080 --> 00:46:23,790 you can reset all of the passwords 944 00:46:23,790 --> 00:46:26,040 across the entire active directory domain. 945 00:46:26,040 --> 00:46:28,500 If you're updating the passwords in SCCM 946 00:46:28,500 --> 00:46:30,660 to make sure that it's still functional, 947 00:46:30,660 --> 00:46:32,220 this certificate will work 948 00:46:32,220 --> 00:46:34,443 to get those credentials after the fact. 949 00:46:37,350 --> 00:46:40,260 Another thing that's kind of interesting is that 950 00:46:40,260 --> 00:46:44,670 if we look at the SMS DP Identity key 951 00:46:44,670 --> 00:46:46,743 and the value reserved one. 952 00:46:47,880 --> 00:46:51,640 I mentioned earlier, anything that starts with 89130000 953 00:46:53,370 --> 00:46:55,740 is probably just using obfuscation, 954 00:46:55,740 --> 00:46:58,980 so it turns out that the actual PXE password 955 00:46:58,980 --> 00:47:03,180 is also stored inside this registry value. 956 00:47:03,180 --> 00:47:04,470 So we can just feed it through 957 00:47:04,470 --> 00:47:06,570 the same deobfuscation function, 958 00:47:06,570 --> 00:47:08,160 get the clear text password. 959 00:47:08,160 --> 00:47:10,320 And again, nice persistence technique 960 00:47:10,320 --> 00:47:12,360 because even if you're recovering the domain, 961 00:47:12,360 --> 00:47:14,940 you're probably not resetting the PXE password. 962 00:47:14,940 --> 00:47:18,753 So you can use this to perform the exact same attack. 963 00:47:19,980 --> 00:47:24,090 And lastly, can we get credentials on endpoints? 964 00:47:24,090 --> 00:47:26,130 How does this work? 965 00:47:26,130 --> 00:47:30,420 Okay, so the really well known method 966 00:47:30,420 --> 00:47:33,060 is to pull the Network Access Account, 967 00:47:33,060 --> 00:47:34,980 the Network Access Account, 968 00:47:34,980 --> 00:47:39,630 and most SCCM configuration options 969 00:47:39,630 --> 00:47:43,770 are stored inside the WMIC database on a given host. 970 00:47:43,770 --> 00:47:47,490 So if we ask for the SCCM Network Access Account clause, 971 00:47:47,490 --> 00:47:49,800 we can see the Network Access Account password, 972 00:47:49,800 --> 00:47:52,470 and the Network Access Account username, 973 00:47:52,470 --> 00:47:55,080 these are marked as policy secrets. 974 00:47:55,080 --> 00:47:59,430 And if we look at the actual data that is being protected, 975 00:47:59,430 --> 00:48:02,610 it's actually protected just using DPAPI. 976 00:48:02,610 --> 00:48:05,973 There's a lot of tools now that can decrypt this, 977 00:48:07,020 --> 00:48:09,930 Benjamin Delpy actually released ages ago, 978 00:48:09,930 --> 00:48:12,044 like about a year, over a year ago, 979 00:48:12,044 --> 00:48:14,340 he built this functionality into MiniCat 980 00:48:14,340 --> 00:48:18,650 so that it can decrypt that specific DPAPI blob. 981 00:48:20,790 --> 00:48:25,593 Recent research from SpecterOps Subat0mik 982 00:48:27,450 --> 00:48:30,500 has built SCCM decryption 983 00:48:30,500 --> 00:48:34,980 of that specific information into SharpDPAPI. 984 00:48:34,980 --> 00:48:37,350 And I'd say one of the most interesting 985 00:48:37,350 --> 00:48:41,520 pieces of recent research is by Adam Chester, 986 00:48:41,520 --> 00:48:44,520 where he's looked at how to register 987 00:48:44,520 --> 00:48:46,380 an arbitrary certificate 988 00:48:46,380 --> 00:48:50,220 for a new domain-joined machine into ECCM, 989 00:48:50,220 --> 00:48:54,150 so that we're able to perform those HTTP requests 990 00:48:54,150 --> 00:48:57,273 in order to pull policies. 991 00:48:58,440 --> 00:49:00,900 So all of these is targeted 992 00:49:00,900 --> 00:49:03,030 towards getting the Network Access Account. 993 00:49:03,030 --> 00:49:05,640 But if you remember, I said, there's three places 994 00:49:05,640 --> 00:49:07,410 that we can pull creds. 995 00:49:07,410 --> 00:49:09,300 So it turns out the collection variables 996 00:49:09,300 --> 00:49:11,100 can also be pushed to endpoints, 997 00:49:11,100 --> 00:49:14,532 so if we query instead of CCM Network Access Account, 998 00:49:14,532 --> 00:49:16,440 if we query CCM collection variable, 999 00:49:16,440 --> 00:49:18,060 we can pull the collection variables, 1000 00:49:18,060 --> 00:49:20,580 these are also marked as policy secrets. 1001 00:49:20,580 --> 00:49:24,840 So we can decrypt it using DPAAPI as well, 1002 00:49:24,840 --> 00:49:28,320 and task sequences might be pushed to endpoints. 1003 00:49:28,320 --> 00:49:29,920 So if we query CCM_tasksequence, 1004 00:49:31,320 --> 00:49:33,810 there's a value called TS_sequence 1005 00:49:33,810 --> 00:49:36,870 that is also a policy secret, 1006 00:49:36,870 --> 00:49:40,680 and is also encrypted using DPAPI. 1007 00:49:40,680 --> 00:49:45,060 Okay, so let's tie everything together. 1008 00:49:45,060 --> 00:49:47,160 We've talked about a whole bunch of ways 1009 00:49:47,160 --> 00:49:49,080 to pull out credentials. 1010 00:49:49,080 --> 00:49:50,343 What are the issues? 1011 00:49:51,780 --> 00:49:55,800 Well, the very first issue is the fact that 1012 00:49:55,800 --> 00:49:59,310 could the accounts configured in SCCM 1013 00:49:59,310 --> 00:50:00,930 might be overly permissioned. 1014 00:50:00,930 --> 00:50:01,980 So right in the beginning, 1015 00:50:01,980 --> 00:50:03,810 I discussed how the Network Access Account 1016 00:50:03,810 --> 00:50:05,250 can be domain admin, 1017 00:50:05,250 --> 00:50:08,940 or it can have administrative access over the SCCM server. 1018 00:50:08,940 --> 00:50:10,740 At the end of the day, this is just an account 1019 00:50:10,740 --> 00:50:14,280 that is used to download software off the SCCM server, 1020 00:50:14,280 --> 00:50:16,050 it doesn't need privileges, 1021 00:50:16,050 --> 00:50:19,140 it needs the ability to log onto an HTTP endpoint. 1022 00:50:19,140 --> 00:50:21,180 It should only have those privileges, 1023 00:50:21,180 --> 00:50:22,410 never mind the fact that 1024 00:50:22,410 --> 00:50:25,060 you don't even need a Network Access Account anymore. 1025 00:50:26,192 --> 00:50:28,500 And that applies to every place 1026 00:50:28,500 --> 00:50:30,090 where you can configure credentials 1027 00:50:30,090 --> 00:50:31,650 in Configuration Manager. 1028 00:50:31,650 --> 00:50:34,680 The Microsoft documentation 1029 00:50:34,680 --> 00:50:37,230 on how to configure these accounts is really good, 1030 00:50:37,230 --> 00:50:39,570 I've put the link to the page 1031 00:50:39,570 --> 00:50:41,673 that discusses this in detail here. 1032 00:50:42,510 --> 00:50:44,910 Read it, it's really good at informing you 1033 00:50:44,910 --> 00:50:46,380 how to configure these accounts 1034 00:50:46,380 --> 00:50:47,850 so that it doesn't contribute 1035 00:50:47,850 --> 00:50:50,340 towards a privilege escalation vector. 1036 00:50:50,340 --> 00:50:53,700 Another issue is that we often have entire teams 1037 00:50:53,700 --> 00:50:56,520 that are dedicated to setting up SCCM. 1038 00:50:56,520 --> 00:50:58,140 So because they're responsible 1039 00:50:58,140 --> 00:51:01,470 for setting up all of the accounts that SCCM uses, 1040 00:51:01,470 --> 00:51:03,060 they might set the same password. 1041 00:51:03,060 --> 00:51:04,980 So we might use different accounts 1042 00:51:04,980 --> 00:51:07,590 that are even appropriately permissioned, 1043 00:51:07,590 --> 00:51:10,770 but if we're taking our administrator account for SCCM 1044 00:51:10,770 --> 00:51:13,470 and setting the same password as the Network Access Account 1045 00:51:13,470 --> 00:51:15,120 that is exposed in this way, 1046 00:51:15,120 --> 00:51:17,640 we can just attempt to use that password 1047 00:51:17,640 --> 00:51:20,790 to gain access to the admin account. 1048 00:51:20,790 --> 00:51:22,290 And if they were set the same, 1049 00:51:22,290 --> 00:51:23,990 cool, we have access to the admin. 1050 00:51:25,410 --> 00:51:30,410 Lastly, we often see that an account configured in SCCM 1051 00:51:31,410 --> 00:51:33,420 is used for multiple purposes. 1052 00:51:33,420 --> 00:51:36,090 So it is pretty well defined, 1053 00:51:36,090 --> 00:51:38,310 you can set a domain-joining credential, 1054 00:51:38,310 --> 00:51:39,873 a Network Access Account, 1055 00:51:41,100 --> 00:51:43,350 a set of credentials that's used 1056 00:51:43,350 --> 00:51:46,740 to connect to a network folder. 1057 00:51:46,740 --> 00:51:49,170 All of these are really well-defined, 1058 00:51:49,170 --> 00:51:51,900 and the problem comes in when we decide, 1059 00:51:51,900 --> 00:51:53,970 we don't actually wanna use different accounts for this, 1060 00:51:53,970 --> 00:51:57,840 so we'll create one account that fulfills all these roles. 1061 00:51:57,840 --> 00:51:59,190 What you're really doing there 1062 00:51:59,190 --> 00:52:01,620 is you're adding additional permissions to accounts 1063 00:52:01,620 --> 00:52:03,180 that don't need them. 1064 00:52:03,180 --> 00:52:06,480 And if you compromise that, you compromise all of the roles 1065 00:52:06,480 --> 00:52:09,423 that, that account is being used for, not a great idea. 1066 00:52:10,800 --> 00:52:13,230 Okay, key takeaways. 1067 00:52:13,230 --> 00:52:15,600 Configuration Manager, super powerful, 1068 00:52:15,600 --> 00:52:17,700 there's a reason it's used so widely. 1069 00:52:17,700 --> 00:52:19,670 I think Patch's management on Windows estate 1070 00:52:19,670 --> 00:52:22,850 is actually pretty painful without using this, 1071 00:52:22,850 --> 00:52:24,660 so it's gonna stick around for a while. 1072 00:52:24,660 --> 00:52:27,030 As long as onsite AD is still the thing, 1073 00:52:27,030 --> 00:52:29,580 Configuration Manager is probably gonna be a thing. 1074 00:52:29,580 --> 00:52:32,670 We've seen here that operating system deployment 1075 00:52:32,670 --> 00:52:35,760 is viable for attacking corporate networks. 1076 00:52:35,760 --> 00:52:38,280 So if we guess the password, 1077 00:52:38,280 --> 00:52:41,070 we can get the certificate, we can pull the policies. 1078 00:52:41,070 --> 00:52:43,320 If the accounts are badly configured, 1079 00:52:43,320 --> 00:52:45,090 we're going to get sensitive credentials, 1080 00:52:45,090 --> 00:52:46,560 and that's going to allow us 1081 00:52:46,560 --> 00:52:48,690 to privileged escalate in the environment. 1082 00:52:48,690 --> 00:52:50,430 It's a really, really, really good idea 1083 00:52:50,430 --> 00:52:53,220 to set a password, and to set a strong password 1084 00:52:53,220 --> 00:52:54,053 and to make sure 1085 00:52:54,053 --> 00:52:56,280 that you're following good password practices. 1086 00:52:56,280 --> 00:52:59,460 Something like using an enterprise password manager here 1087 00:52:59,460 --> 00:53:01,890 where the creds are rotated every now and then, 1088 00:53:01,890 --> 00:53:04,920 and everybody that needs access to these media passwords 1089 00:53:04,920 --> 00:53:06,930 can actually access those passwords 1090 00:53:06,930 --> 00:53:08,403 is probably a good idea. 1091 00:53:09,390 --> 00:53:11,070 If this password is guessed, 1092 00:53:11,070 --> 00:53:12,900 obviously that certificate is compromised, 1093 00:53:12,900 --> 00:53:14,340 and these certificates generally 1094 00:53:14,340 --> 00:53:17,610 at least have a lifetime of around two years. 1095 00:53:17,610 --> 00:53:20,430 And it's very, probably the most important thing, 1096 00:53:20,430 --> 00:53:23,220 is we should make sure that the specific accounts 1097 00:53:23,220 --> 00:53:25,200 that are being pushed to endpoints 1098 00:53:25,200 --> 00:53:28,380 do not have elevated privileges associated to them. 1099 00:53:28,380 --> 00:53:30,450 None of the accounts that we've spoken about, 1100 00:53:30,450 --> 00:53:33,690 that you can get access to need admin access to anything. 1101 00:53:33,690 --> 00:53:38,690 They don't, do not put them inside these policies (giggles) 1102 00:53:39,360 --> 00:53:44,340 because they are exposed, not just to PXE clients, 1103 00:53:44,340 --> 00:53:46,260 but also to every client, 1104 00:53:46,260 --> 00:53:48,450 if you configure task sequences, 1105 00:53:48,450 --> 00:53:51,183 for example, on Windows endpoints. 1106 00:53:52,140 --> 00:53:53,640 If you want some more information, 1107 00:53:53,640 --> 00:53:56,430 I've written up a lot of the stuff 1108 00:53:56,430 --> 00:53:58,890 around the HTTP communications 1109 00:53:58,890 --> 00:54:01,533 at my company's website, MWR CyberSec, 1110 00:54:02,580 --> 00:54:04,293 go have a read at my blog post. 1111 00:54:05,700 --> 00:54:09,060 Again, the tool is going to be released 1112 00:54:09,060 --> 00:54:10,443 on my company's GitHub. 1113 00:54:11,370 --> 00:54:15,000 I'm not there yet, planning to release it this weekend. 1114 00:54:15,000 --> 00:54:17,490 If you wanna know exactly when it comes out, 1115 00:54:17,490 --> 00:54:20,940 feel free to follow me on Twitter or follow my company. 1116 00:54:20,940 --> 00:54:23,512 And that's it, I'm done. 1117 00:54:23,512 --> 00:54:26,679 (audience applauding)