1 00:00:00,210 --> 00:00:01,770 - So awesome, awesome. 2 00:00:01,770 --> 00:00:03,060 I hope everybody's having a good day. 3 00:00:03,060 --> 00:00:04,541 Not very hungover anymore, 4 00:00:04,541 --> 00:00:09,540 but Jake is about to give us a great talk on mainframes and 5 00:00:09,540 --> 00:00:10,373 take it away. 6 00:00:13,260 --> 00:00:15,720 - So this talk is gonna be about 7 00:00:15,720 --> 00:00:19,863 how I found mainframe buffer flows and how you can as well. 8 00:00:21,240 --> 00:00:26,240 So about me, I live in the UK in Basingstoke. 9 00:00:28,470 --> 00:00:33,470 And so my Twitter handle is that if you wanna follow me for 10 00:00:36,030 --> 00:00:38,670 basically mainframe shit posting. 11 00:00:38,670 --> 00:00:39,720 Our slides aren't on? 12 00:00:40,650 --> 00:00:41,483 Oh. 13 00:00:43,830 --> 00:00:45,543 We're going to have to plug something in. 14 00:00:46,806 --> 00:00:47,639 Sorry about that. 15 00:00:47,639 --> 00:00:49,040 - Oh, you're okay. 16 00:00:49,040 --> 00:00:49,873 - Oh yeah. 17 00:00:51,630 --> 00:00:52,463 - You got this. 18 00:00:52,463 --> 00:00:54,088 - Got it, okay, yeah. 19 00:00:54,088 --> 00:00:54,951 Okay. 20 00:00:54,951 --> 00:00:57,951 (audience applauds) 21 00:01:00,500 --> 00:01:01,740 So after university, 22 00:01:01,740 --> 00:01:04,980 I got my first real job as a security consultant. 23 00:01:04,980 --> 00:01:09,980 And at that point I had no clue what a mainframe really was, 24 00:01:10,020 --> 00:01:13,920 but my boss's boss asked if I wanted to do a mainframe job 25 00:01:13,920 --> 00:01:17,713 and I wasn't gonna say no, so I ... 26 00:01:18,660 --> 00:01:23,660 Luckily we had a mainframe emulator, the company had it. 27 00:01:23,850 --> 00:01:25,020 And so during the pandemic, 28 00:01:25,020 --> 00:01:26,670 I was just mucking around with that, 29 00:01:26,670 --> 00:01:31,530 trying to find out how you would do z/OS exploits. 30 00:01:31,530 --> 00:01:35,100 The emulator is a $10,000 USB 31 00:01:35,100 --> 00:01:36,667 you stick in to your computer to say, 32 00:01:36,667 --> 00:01:37,887 "Yes, you can run it." 33 00:01:40,980 --> 00:01:43,380 So around about last May, 34 00:01:43,380 --> 00:01:48,380 I found my first zero day on z/OS and it kind of typifies 35 00:01:48,840 --> 00:01:52,410 how sometimes the z/OS vulnerability 36 00:01:52,410 --> 00:01:54,690 development type thing works. 37 00:01:54,690 --> 00:01:59,690 And so the job had, there was program running on Windows, 38 00:01:59,850 --> 00:02:01,527 Linux, and z/OS. 39 00:02:01,527 --> 00:02:02,580 And for Windows and Linux, 40 00:02:02,580 --> 00:02:04,500 you had the normal requirements. 41 00:02:04,500 --> 00:02:05,580 But for z/OS, 42 00:02:05,580 --> 00:02:07,950 I got told that I could send an email to someone, 43 00:02:07,950 --> 00:02:09,690 they could run it on their computer and 44 00:02:09,690 --> 00:02:11,580 they'd tell me what came up. 45 00:02:11,580 --> 00:02:15,690 Obviously that is just no way to actually test a program. 46 00:02:15,690 --> 00:02:20,690 So I found out that that program that we were gonna test 47 00:02:21,030 --> 00:02:23,460 was on that mainframe emulator we had. 48 00:02:23,460 --> 00:02:28,320 So I just took a month long holiday and worked out that 49 00:02:28,320 --> 00:02:29,910 one of the binaries was vulnerable to 50 00:02:29,910 --> 00:02:32,910 a APF authorized DSA overflow, 51 00:02:32,910 --> 00:02:36,435 which I'll explain where that is later in on the talk. 52 00:02:36,435 --> 00:02:40,621 But the TLDR is that if you are able to get it, 53 00:02:40,621 --> 00:02:42,960 that exploit, 54 00:02:42,960 --> 00:02:45,995 you're able to take full control of the system. 55 00:02:45,995 --> 00:02:50,995 So since then I found a fair number of zero days. 56 00:02:51,060 --> 00:02:52,983 Found one last night. 57 00:02:57,060 --> 00:03:00,150 If you look up on the CVE site, 58 00:03:00,150 --> 00:03:02,550 you can see that there's basically 59 00:03:02,550 --> 00:03:05,130 no vulnerabilities for z/OS. 60 00:03:05,130 --> 00:03:07,200 Don't let someone fool you by saying that that means 61 00:03:07,200 --> 00:03:09,210 it's un-hackable because there's nothing there. 62 00:03:09,210 --> 00:03:11,730 It's because IBMZ doesn't report these, 63 00:03:11,730 --> 00:03:13,272 at least not publicly to everyone. 64 00:03:13,272 --> 00:03:16,380 They tell people on an internal security portal. 65 00:03:16,380 --> 00:03:17,283 So, yeah. 66 00:03:20,613 --> 00:03:23,150 So when people talk about mainframes, 67 00:03:24,120 --> 00:03:25,950 they can mean multiple of things. 68 00:03:25,950 --> 00:03:29,610 They can talk about AS 400, HB NonStop, 69 00:03:29,610 --> 00:03:34,610 z/OS and Z on Linux, or Linux on Z. 70 00:03:35,460 --> 00:03:38,340 And these basically share nothing between each other, 71 00:03:38,340 --> 00:03:40,350 other than the fact that they're big computers. 72 00:03:40,350 --> 00:03:41,580 So for the rest of the talk, 73 00:03:41,580 --> 00:03:44,709 I'm gonna be saying z/OS instead of mainframes, 74 00:03:44,709 --> 00:03:47,973 'cause that's what I'm actually good at exploiting. 75 00:03:49,680 --> 00:03:53,770 So one thing that when you're first starting 76 00:03:54,720 --> 00:03:56,910 learning about z/OS and you know about Linux, 77 00:03:56,910 --> 00:03:59,389 people will tell you things like, 78 00:03:59,389 --> 00:04:03,937 "This feature on feature X on Linux is like 79 00:04:03,937 --> 00:04:06,840 "feature Y on z/OS." 80 00:04:06,840 --> 00:04:11,670 And so one good example of that is files are like data sets. 81 00:04:12,660 --> 00:04:13,633 However, 82 00:04:13,633 --> 00:04:15,750 this is fine for people who are just 83 00:04:15,750 --> 00:04:19,410 regular users of the system or who are pen testing, 84 00:04:19,410 --> 00:04:23,880 just doing a host review of z/OS. 85 00:04:23,880 --> 00:04:27,240 But if you wanna do vulnerability research, 86 00:04:27,240 --> 00:04:28,770 you need to know the nitty gritty of 87 00:04:28,770 --> 00:04:31,380 how these things are actually working. 88 00:04:31,380 --> 00:04:34,500 And so one of the big differences between data sets and 89 00:04:34,500 --> 00:04:38,400 files is that a file is just a load of bites. 90 00:04:38,400 --> 00:04:43,400 And it's the application that chooses how to process that. 91 00:04:44,436 --> 00:04:47,970 But on z/OS, every data set has a, 92 00:04:47,970 --> 00:04:51,660 you define what a data set's format is like beforehand. 93 00:04:51,660 --> 00:04:56,313 So I might say that this data set is a fixed block and 94 00:04:56,313 --> 00:04:59,343 a record length of 80. 95 00:05:01,230 --> 00:05:06,230 This can be where you can have buffer overflows on z/OS, 96 00:05:07,080 --> 00:05:10,383 where you pass at a larger L record than it's expecting. 97 00:05:12,510 --> 00:05:16,260 Another big difference is that z/OS has a flat file system. 98 00:05:16,260 --> 00:05:18,960 So there's no folders. 99 00:05:18,960 --> 00:05:22,110 You might have data sets logically separated. 100 00:05:22,110 --> 00:05:26,580 So you'll have, for example, Jake dot homework dot math, 101 00:05:26,580 --> 00:05:28,357 and you can say, 102 00:05:28,357 --> 00:05:30,937 "Give me all data sets that start with 103 00:05:30,937 --> 00:05:34,230 "the high level qualifier, Jake dot blah-dee-blah." 104 00:05:34,230 --> 00:05:35,190 And it'll give you all of those, 105 00:05:35,190 --> 00:05:36,903 but there's no actual folders. 106 00:05:37,741 --> 00:05:41,280 Then you also have a difference between 107 00:05:41,280 --> 00:05:44,160 sequential and partition data sets. 108 00:05:44,160 --> 00:05:49,160 And the sequential data sets are kind of just normal files. 109 00:05:51,540 --> 00:05:56,010 Partitioned look like a folder and you can enter them and 110 00:05:56,010 --> 00:05:57,690 see that they have lots of different members, 111 00:05:57,690 --> 00:06:02,690 which look like files, but it's underneath the surface, 112 00:06:03,330 --> 00:06:04,630 it's completely different. 113 00:06:07,980 --> 00:06:12,150 So here is an example of a partition data set, 114 00:06:12,150 --> 00:06:17,150 IBM user dot CNTL, and the member is ALOKSTD. 115 00:06:18,390 --> 00:06:22,113 And this is the content of that data set or that member. 116 00:06:22,980 --> 00:06:27,980 And this is a JCL, which is job control language. 117 00:06:29,160 --> 00:06:33,592 And I've heard it described as old timey YAML. 118 00:06:33,592 --> 00:06:36,690 And the way this used to work is 119 00:06:36,690 --> 00:06:37,946 you would have this on a punch card, 120 00:06:37,946 --> 00:06:40,800 you would feed it into the system and then you would check 121 00:06:40,800 --> 00:06:43,380 your line printer for your output. 122 00:06:43,380 --> 00:06:46,500 This doesn't happen anymore, everything is emulated. 123 00:06:46,500 --> 00:06:51,500 The first line of every single JCL is the job card. 124 00:06:55,830 --> 00:06:57,540 And when I say first line, 125 00:06:57,540 --> 00:07:02,540 it's not, lines one to six count on the same line, 126 00:07:02,580 --> 00:07:05,220 because there's a comma at the end of those lines, 127 00:07:05,220 --> 00:07:10,220 which means it's a continuation line, it's just how it is. 128 00:07:12,034 --> 00:07:13,962 And you have different things on here. 129 00:07:13,962 --> 00:07:16,740 The job name, ALOKSTD, 130 00:07:16,740 --> 00:07:19,080 you have message class and message level. 131 00:07:19,080 --> 00:07:20,227 This is what's telling the printer, 132 00:07:20,227 --> 00:07:22,567 "Hey, I want you to print this much information about 133 00:07:22,567 --> 00:07:24,450 "what happened on a job." 134 00:07:24,450 --> 00:07:27,420 And you also have something called user and password. 135 00:07:27,420 --> 00:07:32,040 This is kind of like SUSE on Linux, 136 00:07:32,040 --> 00:07:34,260 where you can submit a job as another user, 137 00:07:34,260 --> 00:07:36,750 either by providing both the username and password, 138 00:07:36,750 --> 00:07:39,213 or just the user and having access to do that. 139 00:07:40,650 --> 00:07:43,390 The next line, the step 01 is 140 00:07:46,634 --> 00:07:50,203 a step which runs the program IEFBR 14, 141 00:07:52,322 --> 00:07:55,290 that then also has on the next line, 142 00:07:55,290 --> 00:07:56,670 a DD statement. 143 00:07:56,670 --> 00:08:00,630 And what the DD statement means is that IEFBR 14, 144 00:08:00,630 --> 00:08:03,810 can reference a DD fixed 32760. 145 00:08:03,810 --> 00:08:06,750 It could write to it, it could read from it and 146 00:08:06,750 --> 00:08:09,903 it would then write to that data set. 147 00:08:12,960 --> 00:08:16,710 So what happens is every time you start a new job, 148 00:08:16,710 --> 00:08:19,380 it has its own address space. 149 00:08:19,380 --> 00:08:22,808 And this is also a good example of where 150 00:08:22,808 --> 00:08:26,640 comparing Linux and z/OS kind of falls apart. 151 00:08:26,640 --> 00:08:31,640 So people often compare the nucleus and the CSA 152 00:08:33,754 --> 00:08:38,754 of z/OS to, or Z Arch to the Linux Colonel. 153 00:08:38,760 --> 00:08:43,110 But as you can see on here, every drop on the system, 154 00:08:43,110 --> 00:08:44,520 no matter what program you're running, 155 00:08:44,520 --> 00:08:46,350 has the ability to address the nucleus, 156 00:08:46,350 --> 00:08:50,700 which is something which you can't do on Linux in just 157 00:08:50,700 --> 00:08:52,140 addressing it normally. 158 00:08:52,140 --> 00:08:53,460 And also if, for example, 159 00:08:53,460 --> 00:08:56,010 you are able to write to the nucleus or the CSA, 160 00:08:56,010 --> 00:08:58,650 you would be able to fully break the system. 161 00:08:58,650 --> 00:09:03,650 So these are protected, but yeah, I'll get to that later. 162 00:09:05,730 --> 00:09:10,320 Then the next important parts of memory is that you have 163 00:09:10,320 --> 00:09:12,510 some private memory and this can be divided into 164 00:09:12,510 --> 00:09:14,820 private high and private low. 165 00:09:14,820 --> 00:09:16,620 Private high memory is memory that is 166 00:09:16,620 --> 00:09:18,960 shared between all steps in a job. 167 00:09:18,960 --> 00:09:20,103 So for example, 168 00:09:21,000 --> 00:09:25,380 you might, in that JCL we had, that job name would be some 169 00:09:25,380 --> 00:09:26,970 addressable part of memory, 170 00:09:26,970 --> 00:09:31,323 and that would be the same in every single step. 171 00:09:33,240 --> 00:09:34,140 Yeah? 172 00:09:34,140 --> 00:09:35,340 And then there's private low, 173 00:09:35,340 --> 00:09:39,240 which you could consider basically normal, 174 00:09:39,240 --> 00:09:42,146 like if a program needs memory to run its actual program, 175 00:09:42,146 --> 00:09:43,946 that's where it'll be running it to. 176 00:09:45,000 --> 00:09:47,613 If you're wondering how ASLR works on z/OS, 177 00:09:48,630 --> 00:09:51,780 it only moves around the private low memory. 178 00:09:51,780 --> 00:09:54,630 So this is how I bypass ASLR, 179 00:09:54,630 --> 00:09:59,630 is I just find some gadgets in private high or the nucleus, 180 00:09:59,933 --> 00:10:01,443 'cause that won't move. 181 00:10:04,110 --> 00:10:08,340 So another important thing about Z Arch is that 182 00:10:08,340 --> 00:10:11,643 instead of having things like the instruction, 183 00:10:14,138 --> 00:10:17,010 the instruction register or condition code registers, 184 00:10:17,010 --> 00:10:18,540 this is all in memory. 185 00:10:18,540 --> 00:10:23,540 So, and this is called a PSW or program status word. 186 00:10:24,390 --> 00:10:25,223 And so you can see it's got 187 00:10:25,223 --> 00:10:27,960 the instructional address and the condition code. 188 00:10:27,960 --> 00:10:30,270 But the other thing which is important about Z Arch is 189 00:10:30,270 --> 00:10:32,850 you also have two more things. 190 00:10:32,850 --> 00:10:36,210 You have supervisor state and the key. 191 00:10:36,210 --> 00:10:38,010 What supervisor state is, 192 00:10:38,010 --> 00:10:41,370 is it allows you to run all the fun instructions on Z Arch 193 00:10:41,370 --> 00:10:44,820 that let you, so for example, change key, 194 00:10:44,820 --> 00:10:47,968 or there's an instruction called NBCS, 195 00:10:47,968 --> 00:10:51,180 which lets you just write to another address space. 196 00:10:51,180 --> 00:10:55,853 So if you're in that, it's quite good. 197 00:10:55,853 --> 00:11:00,853 And then the key is every single page of memory is protected 198 00:11:01,500 --> 00:11:05,430 by a storage key and you need to have 199 00:11:05,430 --> 00:11:07,200 the correct key to access it. 200 00:11:07,200 --> 00:11:11,340 So if I wanted to write just some key four memory, 201 00:11:11,340 --> 00:11:13,620 I would need to be in key four. 202 00:11:13,620 --> 00:11:18,210 And also if I want to read from that memory, 203 00:11:18,210 --> 00:11:19,470 if it's fetch protected, 204 00:11:19,470 --> 00:11:21,510 which is a way you can set it to be, 205 00:11:21,510 --> 00:11:23,340 you also need to be in key four. 206 00:11:23,340 --> 00:11:26,400 So there's also one additional thing. 207 00:11:26,400 --> 00:11:27,960 Whereas if you're in key zero, 208 00:11:27,960 --> 00:11:30,023 you're allowed to access anything you want. 209 00:11:32,340 --> 00:11:36,842 So what would we do if we could write to anything we want? 210 00:11:36,842 --> 00:11:40,560 We would want to escalate our privileges and the way we do 211 00:11:40,560 --> 00:11:44,670 this is by editing the z/OS ACEE. 212 00:11:44,670 --> 00:11:47,433 And you can think of this like a UID or a GUID, 213 00:11:48,660 --> 00:11:53,400 but it's in our own address space in 214 00:11:53,400 --> 00:11:55,690 a private high storage. 215 00:11:59,160 --> 00:12:02,400 So it's the same across every single job. 216 00:12:02,400 --> 00:12:07,400 So if we could write to this ACEE, 217 00:12:07,770 --> 00:12:12,000 we're able to change our privileges in one step, 218 00:12:12,000 --> 00:12:14,537 then in the next step say, 219 00:12:14,537 --> 00:12:16,260 so for example, 220 00:12:16,260 --> 00:12:19,980 one of the privileges we'd give ourselves is RAKF special. 221 00:12:19,980 --> 00:12:22,050 And what this does is it says, 222 00:12:22,050 --> 00:12:25,740 anytime I want to, anytime, 223 00:12:25,740 --> 00:12:30,300 anytime I want to give myself access to something, 224 00:12:30,300 --> 00:12:32,490 say I'm allowed to give myself access to it. 225 00:12:32,490 --> 00:12:34,050 So we just flip that in one step, 226 00:12:34,050 --> 00:12:37,080 we flip our ACEE bit in one bit, give ourselves special. 227 00:12:37,080 --> 00:12:39,577 And then the next step we just say, 228 00:12:39,577 --> 00:12:41,490 "Also give us access to everything." 229 00:12:41,490 --> 00:12:45,889 And then yeah, 230 00:12:45,889 --> 00:12:48,210 but this is stored in key zero memory. 231 00:12:48,210 --> 00:12:50,670 So not only certain types of programs are 232 00:12:50,670 --> 00:12:52,353 allowed to edit this. 233 00:12:54,600 --> 00:12:56,430 So how do we edit it? 234 00:12:56,430 --> 00:13:00,150 We can just use a simple Z Arch assembly program, 235 00:13:00,150 --> 00:13:02,534 which uses mode set, 236 00:13:02,534 --> 00:13:07,534 which allows us to go into key zero or supervisor state. 237 00:13:08,970 --> 00:13:12,480 And you're only allowed to use this if you yourself are in 238 00:13:12,480 --> 00:13:13,830 supervisor state, 239 00:13:13,830 --> 00:13:16,893 or if you have a cert or if you're running APF authorized. 240 00:13:17,910 --> 00:13:21,000 So after we get into key zero, 241 00:13:21,000 --> 00:13:25,440 we load our, through what's called control blocks. 242 00:13:25,440 --> 00:13:29,640 And we find out where our ACEE is in memory. 243 00:13:29,640 --> 00:13:31,950 We then just flip a bit that says we're special, 244 00:13:31,950 --> 00:13:33,243 and we're good. 245 00:13:34,230 --> 00:13:39,230 This is part of the reason why IBM was only able to put ASLR 246 00:13:39,360 --> 00:13:41,550 on the private low memory, 247 00:13:41,550 --> 00:13:43,290 because if they put it on everything, 248 00:13:43,290 --> 00:13:45,240 they would end up breaking all the control blocks, 249 00:13:45,240 --> 00:13:47,400 which would break all the other programs 250 00:13:47,400 --> 00:13:48,700 that are actually running. 251 00:13:50,610 --> 00:13:53,790 So how do we get into supervisor state? 252 00:13:53,790 --> 00:13:57,690 So we could either be running an SVC or a PC. 253 00:13:57,690 --> 00:14:02,280 These are like syscalls on Linux, 254 00:14:02,280 --> 00:14:04,113 but just completely different. 255 00:14:05,850 --> 00:14:09,150 And then there's also what I'm gonna be talking about for 256 00:14:09,150 --> 00:14:10,470 the majority of this talk, 257 00:14:10,470 --> 00:14:13,173 which is APF authorized data sets. 258 00:14:14,640 --> 00:14:17,340 So if we wanna run a program, APF authorized, 259 00:14:17,340 --> 00:14:18,690 we need two things to be true. 260 00:14:18,690 --> 00:14:22,860 It needs to be part of the list of APF authorized libraries. 261 00:14:22,860 --> 00:14:26,580 And also the AC one flag has to be set. 262 00:14:26,580 --> 00:14:28,500 So if, for example, 263 00:14:28,500 --> 00:14:32,340 we had write access to an APF authorized library, 264 00:14:32,340 --> 00:14:35,100 all we would have to do is compile that previous code 265 00:14:35,100 --> 00:14:39,993 I showed and compile it with that AC one flag and 266 00:14:41,970 --> 00:14:44,610 we would be, have full access. 267 00:14:44,610 --> 00:14:45,990 This isn't often. 268 00:14:45,990 --> 00:14:48,420 I've never seen it where, 269 00:14:48,420 --> 00:14:50,220 since I've been testing mainframes, 270 00:14:50,220 --> 00:14:51,630 I've never seen it where I could just write to 271 00:14:51,630 --> 00:14:53,073 an APF authorized data set. 272 00:14:56,310 --> 00:15:01,200 Okay, so now we're going to assume that there, 273 00:15:01,200 --> 00:15:02,085 we can't write to it, 274 00:15:02,085 --> 00:15:03,810 but there is some vulnerable program that 275 00:15:03,810 --> 00:15:05,673 someone has written that's AC one. 276 00:15:06,690 --> 00:15:09,180 So how do we find these vulnerable programs? 277 00:15:09,180 --> 00:15:10,920 What we're looking for are abends and 278 00:15:10,920 --> 00:15:14,250 these are kind of like seg faults in Linux. 279 00:15:14,250 --> 00:15:16,590 And there's two main categories. 280 00:15:16,590 --> 00:15:19,140 We have system and user abends. 281 00:15:19,140 --> 00:15:21,570 We're just gonna ignore user abends for the time being, 282 00:15:21,570 --> 00:15:23,883 because that's kind, people, 283 00:15:24,803 --> 00:15:28,710 mainframers normally use that to, with the regular, 284 00:15:28,710 --> 00:15:32,220 it's an expected bad input that someone's given, 285 00:15:32,220 --> 00:15:33,810 gives you a user abend, 286 00:15:33,810 --> 00:15:36,900 a system abend is normally something that happens that 287 00:15:36,900 --> 00:15:39,990 the program didn't even realize that that could happen. 288 00:15:39,990 --> 00:15:43,848 So there's the three main ones that I'm looking for. 289 00:15:43,848 --> 00:15:45,515 SOC4, SOC1 and SOC6. 290 00:15:46,892 --> 00:15:50,610 SOC4 means that we've tried to address an area of memory 291 00:15:50,610 --> 00:15:53,793 that we don't have the right key to, 292 00:15:54,718 --> 00:15:56,333 or just the memory doesn't exist. 293 00:15:57,630 --> 00:15:59,790 Then there's also SOC6. 294 00:15:59,790 --> 00:16:04,790 And so in Z Arch, 295 00:16:05,010 --> 00:16:09,390 every instruction has to be on a half word boundary. 296 00:16:09,390 --> 00:16:11,730 And if it's not, you get a SOC6 event. 297 00:16:11,730 --> 00:16:14,503 So everything needs to be on an even bite. 298 00:16:14,503 --> 00:16:16,650 And then SOC1 means that 299 00:16:16,650 --> 00:16:19,536 we've tried to execute an instruction, 300 00:16:19,536 --> 00:16:21,570 but the operand in op code don't make sense. 301 00:16:21,570 --> 00:16:24,270 It doesn't, it's not a real instruction. 302 00:16:24,270 --> 00:16:26,250 And if you want to find out more about 303 00:16:26,250 --> 00:16:27,220 all the different abends you can read 304 00:16:27,220 --> 00:16:31,083 IBM's 854 page manual about every single one. 305 00:16:34,170 --> 00:16:37,860 Okay, so we now know that we're looking for abends. 306 00:16:37,860 --> 00:16:40,023 How do we work out what caused that abend? 307 00:16:41,550 --> 00:16:45,664 The one I normally am going for is using a SYSUDUMP. 308 00:16:45,664 --> 00:16:48,600 An SYSUDUMP means a user formatted dump. 309 00:16:48,600 --> 00:16:51,690 So we can just print this out to any random data set 310 00:16:51,690 --> 00:16:54,183 so we can, and we can read it. It's human readable. 311 00:16:55,470 --> 00:16:57,540 And I'll explain later what's actually in it. 312 00:16:57,540 --> 00:16:59,070 Then we have a CEEDUMP, 313 00:16:59,070 --> 00:17:03,780 which is only for some very specific compiled programs in 314 00:17:03,780 --> 00:17:04,920 language environment. 315 00:17:04,920 --> 00:17:06,690 I'll explain where that is later. 316 00:17:06,690 --> 00:17:09,180 But the problem with this for us is 317 00:17:09,180 --> 00:17:11,940 because we break so much stuff when we're causing abends. 318 00:17:11,940 --> 00:17:15,130 Sometimes we even break it, generating the CEEDUMP. 319 00:17:17,310 --> 00:17:20,430 And then there is SYSMDUMP, 320 00:17:20,430 --> 00:17:24,090 which gives you so much information. 321 00:17:24,090 --> 00:17:25,710 And it's also not human readable. 322 00:17:25,710 --> 00:17:29,010 You need to put it through another program called IPCS that 323 00:17:29,010 --> 00:17:30,540 I just don't bother with it. 324 00:17:30,540 --> 00:17:33,033 Normally, everything I need is in a SYSUDUMP. 325 00:17:36,210 --> 00:17:40,410 Okay, so how do we cause a dump to be generated? 326 00:17:40,410 --> 00:17:42,273 We just add a DD statement. 327 00:17:43,590 --> 00:17:44,973 So here is a, 328 00:17:46,320 --> 00:17:51,320 here's a JCL to run our FTPD server and we've added 329 00:17:51,330 --> 00:17:54,060 a SYSUDUMP DD CIS out equal star. 330 00:17:54,060 --> 00:17:55,410 So now when the program abends, 331 00:17:55,410 --> 00:17:57,210 we'll be able to see a long list of 332 00:17:57,210 --> 00:17:59,253 all the things that were in there. 333 00:18:00,450 --> 00:18:04,463 This is the, instead of using, 334 00:18:04,463 --> 00:18:07,140 instead of practicing exploit, 335 00:18:07,140 --> 00:18:09,153 dev form, dev stuff on z/OS, 336 00:18:10,140 --> 00:18:13,500 I like going through NVS 3.8J. 337 00:18:13,500 --> 00:18:17,040 It's a 50 year old operating system that's in 338 00:18:17,040 --> 00:18:18,600 the public domain. 339 00:18:18,600 --> 00:18:20,520 So anyone can just spin up a Docker. 340 00:18:20,520 --> 00:18:22,923 You don't require a $10,000 USB to run it, 341 00:18:25,140 --> 00:18:30,030 but all of the exploit techniques are the same on MBS 3.8J 342 00:18:30,030 --> 00:18:32,163 as modern z/OS. 343 00:18:34,170 --> 00:18:36,821 So what's actually in a SYSUDUMP? 344 00:18:36,821 --> 00:18:37,654 So we have our PSW, 345 00:18:37,654 --> 00:18:40,620 which is gonna tell us our instruction pointer and 346 00:18:40,620 --> 00:18:42,370 what key we're in when we abend it. 347 00:18:43,230 --> 00:18:44,880 We're also gonna get our completion code. 348 00:18:44,880 --> 00:18:48,780 So this will be like SOC4, SOC6. 349 00:18:48,780 --> 00:18:51,930 And we also, we might get a little reason code. 350 00:18:51,930 --> 00:18:55,857 So some extra information about why it abended. 351 00:18:55,857 --> 00:18:58,230 We also get our list of registers that, 352 00:18:58,230 --> 00:19:00,690 16 general purpose registers. 353 00:19:00,690 --> 00:19:05,690 And when we also have a list of sub pools, 354 00:19:06,750 --> 00:19:10,890 and sub pools are, when I showed you that memory map, 355 00:19:10,890 --> 00:19:13,110 you're allowed to ask the system for 356 00:19:13,110 --> 00:19:14,673 different parts of that, 357 00:19:16,680 --> 00:19:18,480 different parts of that memory. 358 00:19:18,480 --> 00:19:20,017 And so this is useful for saying, 359 00:19:20,017 --> 00:19:24,393 "Okay, what memory and where has my program got, 360 00:19:25,373 --> 00:19:28,257 "what memory has my program allocated?" 361 00:19:29,160 --> 00:19:31,859 And then we also get a big dump of 362 00:19:31,859 --> 00:19:36,023 all of the contents of what was in the dumps, 363 00:19:39,510 --> 00:19:43,863 the subpools we actually have access to. 364 00:19:46,410 --> 00:19:51,060 So it's when we get a dump, 365 00:19:51,060 --> 00:19:53,280 we need to know what we're actually looking for. 366 00:19:53,280 --> 00:19:57,990 And so most programs on z/OS will be 367 00:19:57,990 --> 00:20:00,120 compiled language environment. 368 00:20:00,120 --> 00:20:01,470 What language environment is, 369 00:20:01,470 --> 00:20:06,470 is it's kind of a common way for things to be compiled and 370 00:20:07,260 --> 00:20:09,543 for what registers will contain what. 371 00:20:13,140 --> 00:20:15,000 So for example, if you compile a C program, 372 00:20:15,000 --> 00:20:17,370 it'll be compiled language environment, 373 00:20:17,370 --> 00:20:21,450 and then that will also have DSAs, dynamic save areas. 374 00:20:21,450 --> 00:20:26,450 If you, one where Z Arch doesn't have a stack. 375 00:20:27,090 --> 00:20:29,100 So we have to create a stack in memory, 376 00:20:29,100 --> 00:20:31,470 because stacks are useful. 377 00:20:31,470 --> 00:20:36,470 So I'll explain how a DSA overflow works, 378 00:20:37,530 --> 00:20:38,670 but you can kind of think of it as 379 00:20:38,670 --> 00:20:40,713 a linked list of a lot of stacks. 380 00:20:44,223 --> 00:20:48,960 So just gonna explain a DSA overflow, this is just a simple, 381 00:20:48,960 --> 00:20:51,000 nothing code that uses gets. 382 00:20:51,000 --> 00:20:53,190 So it's, the vulnerability is obvious, 383 00:20:53,190 --> 00:20:55,640 but the exploit is a little bit more interesting. 384 00:20:56,850 --> 00:20:59,500 So the first thing we do is that 385 00:21:00,660 --> 00:21:02,700 when we're about to call gets, 386 00:21:02,700 --> 00:21:05,850 our caller DSA has a next available bite, 387 00:21:05,850 --> 00:21:07,113 just some free memory. 388 00:21:08,631 --> 00:21:10,110 And because we're calling gets, 389 00:21:10,110 --> 00:21:11,880 we can also see that we have a parameter list, 390 00:21:11,880 --> 00:21:16,470 which has in register, which has just one parameter, 391 00:21:16,470 --> 00:21:18,363 which is the buffer address. 392 00:21:24,060 --> 00:21:26,130 Now, once the gets program start, 393 00:21:26,130 --> 00:21:29,550 once the gets function starts, it will create its DSA. 394 00:21:29,550 --> 00:21:32,913 And we'll also save the contents of 395 00:21:32,913 --> 00:21:35,430 our main functions' registers 396 00:21:35,430 --> 00:21:37,290 so that once we're finished with gets, 397 00:21:37,290 --> 00:21:39,933 we can go restore everything we had beforehand. 398 00:21:43,410 --> 00:21:47,070 We also set a previous pointer in the gets DSA 399 00:21:47,070 --> 00:21:50,373 so that we know where our caller DSA is. 400 00:21:54,360 --> 00:21:59,070 Then, so to exploit it, we just give it a long buffer. 401 00:21:59,070 --> 00:22:03,900 And because the buffer that we're using is before 402 00:22:03,900 --> 00:22:06,810 our gets DSA will end up overflowing, 403 00:22:06,810 --> 00:22:11,038 our previous DSA pointer in the gets DSA. 404 00:22:11,038 --> 00:22:15,840 And so I've put for reasons, 405 00:22:15,840 --> 00:22:19,073 I put a long list of LGBT LGBT, LGBT, 406 00:22:19,073 --> 00:22:21,330 LGBT and then ended with kale. 407 00:22:21,330 --> 00:22:24,000 And then when the gets function ends, 408 00:22:24,000 --> 00:22:27,150 what it's gonna try and do is restore its DSA. 409 00:22:27,150 --> 00:22:30,690 But it thinks that the DSA is located at address kale. 410 00:22:30,690 --> 00:22:33,893 Kale is not a real address, and so it will abend. 411 00:22:36,840 --> 00:22:38,853 So then instead of doing this, 412 00:22:38,853 --> 00:22:41,643 what we do is we fill it with, 413 00:22:43,140 --> 00:22:45,090 we actually write an exploit for it. 414 00:22:45,090 --> 00:22:46,980 So instead of the previous pointer pointing to 415 00:22:46,980 --> 00:22:51,980 some random address, we point it to our buffer. 416 00:22:52,080 --> 00:22:54,771 Then it will restore all of its registers that 417 00:22:54,771 --> 00:22:59,771 it thought it had when the get function was called. 418 00:23:01,590 --> 00:23:04,170 But at the moment it's restoring from our buffer. 419 00:23:04,170 --> 00:23:07,767 One of those registers it's gonna restore is 420 00:23:12,210 --> 00:23:13,710 register 14. 421 00:23:13,710 --> 00:23:15,606 14 in a language environment is 422 00:23:15,606 --> 00:23:20,606 an important register because it's the return register. 423 00:23:21,660 --> 00:23:23,760 The reason why is because 424 00:23:23,760 --> 00:23:28,667 the typical way to call a function in z/OS, Z Arch Assembly 425 00:23:29,880 --> 00:23:34,443 is a instruction called branch and link register R14, R15. 426 00:23:35,460 --> 00:23:37,597 And that says, "Jump to R15 and store 427 00:23:37,597 --> 00:23:41,097 "the next instruction in memory in R14." 428 00:23:42,210 --> 00:23:45,810 So now we've taken over the return register. 429 00:23:45,810 --> 00:23:47,877 We then just point that towards our buffer. 430 00:23:47,877 --> 00:23:51,810 And then because we're running as APF authorized code, 431 00:23:51,810 --> 00:23:56,310 we can just run our AKI flipping code that I showed before. 432 00:23:56,310 --> 00:23:57,902 And now that's the case. 433 00:23:57,902 --> 00:24:02,902 In the next step we can just give ourselves privileges to 434 00:24:04,830 --> 00:24:05,853 access anything. 435 00:24:08,565 --> 00:24:10,170 So that FTP server on the MVS 3.8J is vulnerable and 436 00:24:18,000 --> 00:24:20,280 it's vulnerable to a DSA overflow. 437 00:24:20,280 --> 00:24:25,280 So all we have to do is just keep crashing the FTP server by 438 00:24:25,380 --> 00:24:28,890 giving it a, I'm not gonna go through the vulnerability, 439 00:24:28,890 --> 00:24:32,250 'cause it's just a simple C vulnerability, but it's just, 440 00:24:32,250 --> 00:24:35,430 you give it a user, space and then a long list and 441 00:24:35,430 --> 00:24:36,380 it crashes on that. 442 00:24:39,300 --> 00:24:40,133 So yeah. 443 00:24:40,133 --> 00:24:41,970 So all we have to do is just keep working out 444 00:24:41,970 --> 00:24:44,550 what register is being filled with what buffer, 445 00:24:44,550 --> 00:24:48,510 then find out when we change that previous DSA pointer, 446 00:24:48,510 --> 00:24:50,310 point it towards our buffer and then 447 00:24:50,310 --> 00:24:53,010 edit the return register and then run some shell code. 448 00:24:54,780 --> 00:24:59,780 So if you use a mainframe, one of the useful tools on there, 449 00:25:00,663 --> 00:25:02,190 it's something called REXX. 450 00:25:02,190 --> 00:25:04,803 It's somewhere between Bash and Python. 451 00:25:06,222 --> 00:25:10,093 And so I often use this for generating a Debruijn String on, 452 00:25:12,720 --> 00:25:14,640 I can use this to generate a data set, 453 00:25:14,640 --> 00:25:17,850 which contains a Debruijn String. 454 00:25:17,850 --> 00:25:18,840 And then I can then use that to 455 00:25:18,840 --> 00:25:21,060 try and look for vulnerabilities, 456 00:25:21,060 --> 00:25:24,210 but we'll use it to crash the FTP server by 457 00:25:24,210 --> 00:25:26,733 giving it a user space Debruijn String. 458 00:25:28,170 --> 00:25:31,966 And what's kind of curious about 459 00:25:31,966 --> 00:25:36,966 doing an RCE against z/OS of NVS 3.8J is that 460 00:25:38,520 --> 00:25:40,510 most servers are expecting 461 00:25:42,510 --> 00:25:45,530 ASCII text from a normal host and 462 00:25:45,530 --> 00:25:48,780 is gonna translate that into EBCDIC. 463 00:25:48,780 --> 00:25:52,530 And so when we've passed our normal buffer of 464 00:25:52,530 --> 00:25:54,000 just the load of characters, 465 00:25:54,000 --> 00:25:58,800 it's actually translated that into EBCDIC. 466 00:25:58,800 --> 00:26:03,800 So 41 will become C one and this is gonna become, 467 00:26:03,960 --> 00:26:07,140 this makes RCEs on z/OS quite tricky, 468 00:26:07,140 --> 00:26:09,960 because you have to think about this before you 469 00:26:09,960 --> 00:26:10,893 send your buffer. 470 00:26:13,080 --> 00:26:16,860 So if we look at the registers in our SYSUDUMP, 471 00:26:16,860 --> 00:26:21,320 we can see that register two has been overflown by 472 00:26:21,320 --> 00:26:22,953 an EBCDIC string. 473 00:26:24,900 --> 00:26:26,970 We then, we also see that there's a SOC4, 474 00:26:29,010 --> 00:26:32,610 so we can see that in our register two, 475 00:26:32,610 --> 00:26:35,520 we had 88F8C288, 476 00:26:35,520 --> 00:26:37,980 but the actual binary that, 477 00:26:37,980 --> 00:26:42,213 the actual bites that we sent to it was 68384268. 478 00:26:44,520 --> 00:26:48,460 So what this means is that 479 00:26:49,560 --> 00:26:52,530 the translation table between ASCII and EBCDIC 480 00:26:52,530 --> 00:26:53,760 isn't one to one. 481 00:26:53,760 --> 00:26:57,270 So some bites will both convert down to the same, 482 00:26:57,270 --> 00:26:59,220 convert to the same bite. 483 00:26:59,220 --> 00:27:02,297 So for example, on the default IBM z/OS translation table 484 00:27:02,297 --> 00:27:06,450 00 and 80 both convert to 00. 485 00:27:06,450 --> 00:27:09,120 But what's more annoying about that is that means 486 00:27:09,120 --> 00:27:11,850 there's some bites that have nothing to convert into it. 487 00:27:11,850 --> 00:27:16,850 So if we needed in our buffer, a zero nine to occur, 488 00:27:18,750 --> 00:27:20,806 it's not possible, you just can't. 489 00:27:20,806 --> 00:27:24,270 There isn't an ASCII bit that will translate to that. 490 00:27:24,270 --> 00:27:29,220 So it is somewhat frustrating when even though it's 491 00:27:29,220 --> 00:27:31,630 vulnerable and it looks exploitable, 492 00:27:31,630 --> 00:27:33,723 we had to change it to zero nine. 493 00:27:34,800 --> 00:27:36,720 So yeah, it means that some addresses are 494 00:27:36,720 --> 00:27:37,920 just un-addressable. 495 00:27:37,920 --> 00:27:40,830 It also means that we need to encode our shell code 496 00:27:40,830 --> 00:27:42,780 so that everything translates properly. 497 00:27:45,360 --> 00:27:48,660 So how do we work out 498 00:27:48,660 --> 00:27:50,580 the instructions that we're abending on, 499 00:27:50,580 --> 00:27:52,410 what's actually causing the abends? 500 00:27:52,410 --> 00:27:57,410 So I've written a REXX script to just translate, 501 00:28:00,000 --> 00:28:04,743 to disassemble like eight bites to a, it's Z Arch Assembly, 502 00:28:06,180 --> 00:28:08,230 mostly grabbed from someone else's stuff. 503 00:28:09,090 --> 00:28:14,040 And so if we wanna find out what instruction we abended on, 504 00:28:14,040 --> 00:28:16,263 we have a look at our instruction pointer. 505 00:28:17,220 --> 00:28:19,170 We then take that instruction pointer, 506 00:28:19,170 --> 00:28:24,170 have a look at the memory, the address where it occurred. 507 00:28:30,500 --> 00:28:31,710 We then take that instruction, 508 00:28:31,710 --> 00:28:33,750 run it through to CoDi and find out it's 509 00:28:33,750 --> 00:28:38,750 a store multiple R12R140R2. 510 00:28:38,760 --> 00:28:43,760 And this is writing at R2. 511 00:28:44,010 --> 00:28:45,750 And this is why we got a SOC4, 512 00:28:45,750 --> 00:28:49,200 because it tried to write to that register 513 00:28:49,200 --> 00:28:50,193 we've overflown. 514 00:28:53,580 --> 00:28:56,250 So how do we solve this? 515 00:28:56,250 --> 00:28:58,440 Well, we need to find some area of memory, 516 00:28:58,440 --> 00:29:00,210 which is in key eight, 517 00:29:00,210 --> 00:29:02,610 because if you looked at our PSW at that time, 518 00:29:02,610 --> 00:29:05,272 we were in key eight, it also needs to be, 519 00:29:05,272 --> 00:29:09,510 we then need to create an address which will 520 00:29:09,510 --> 00:29:10,680 convert to something. 521 00:29:10,680 --> 00:29:15,570 So, I just chose this one because it converted to 522 00:29:15,570 --> 00:29:17,790 something that we have access to. 523 00:29:17,790 --> 00:29:20,430 And also to note that in z/OS there's 524 00:29:20,430 --> 00:29:22,230 three types of addressing modes. 525 00:29:22,230 --> 00:29:27,230 There's 24 bit, there's 31 bit for some reason and 64 bit. 526 00:29:29,370 --> 00:29:32,970 So this is at the moment in 24 bits, so only three bites. 527 00:29:32,970 --> 00:29:33,803 And then, 528 00:29:33,803 --> 00:29:37,200 so we keep doing it and we see that there's another abend. 529 00:29:37,200 --> 00:29:40,230 This one's not particularly interesting, 530 00:29:40,230 --> 00:29:42,660 but the next one is. 531 00:29:42,660 --> 00:29:47,660 So register 13 is mostly used as the current DSA pointer. 532 00:29:49,980 --> 00:29:52,920 So if we've overwritten register 13, 533 00:29:52,920 --> 00:29:55,230 it often means that we're onto something good. 534 00:29:55,230 --> 00:29:57,247 And we can have a look and we can see that, 535 00:29:57,247 --> 00:29:59,250 "So register 13 is overwritten." 536 00:29:59,250 --> 00:30:02,280 We have a look at the instruction that we've tried to run, 537 00:30:02,280 --> 00:30:05,523 and it is load R14, R12, R13. 538 00:30:06,540 --> 00:30:09,180 And I've also decoded the next couple of instructions, 539 00:30:09,180 --> 00:30:11,800 because this is the normal way that you would 540 00:30:13,260 --> 00:30:15,930 exit a function and restore your DSA. 541 00:30:15,930 --> 00:30:18,330 So you are loading your return register, 542 00:30:18,330 --> 00:30:20,640 then you're loading all your other registers and then 543 00:30:20,640 --> 00:30:24,150 you're branching with the bit mask 1111, 544 00:30:24,150 --> 00:30:27,690 which means branch every time to register 14. 545 00:30:27,690 --> 00:30:31,890 So that's where, that's why overwriting register 14 546 00:30:31,890 --> 00:30:33,890 lets us control the instruction pointer. 547 00:30:35,850 --> 00:30:36,683 Okay. 548 00:30:36,683 --> 00:30:41,420 So this is where we've now restored 549 00:30:42,600 --> 00:30:46,470 all of those registers from our buffer. 550 00:30:46,470 --> 00:30:48,630 And you can see that now every register has been replaced. 551 00:30:48,630 --> 00:30:50,823 This was the load multiple that happened. 552 00:30:52,530 --> 00:30:55,860 And you can also see that the instruction pointer has now 553 00:30:55,860 --> 00:31:00,860 been changed to C182F5, which was from our buffer. 554 00:31:05,610 --> 00:31:10,610 And also you can see that this is SOC6 because F5 is not on 555 00:31:10,740 --> 00:31:12,300 a half word boundary. 556 00:31:12,300 --> 00:31:14,223 So it's another, yeah. 557 00:31:15,360 --> 00:31:20,360 Okay, so now that we've edited all of our registers, 558 00:31:20,670 --> 00:31:22,350 we wanna edit the return address to point to 559 00:31:22,350 --> 00:31:24,810 somewhere that we have control over. 560 00:31:24,810 --> 00:31:27,990 And so we just choose somewhere that, 561 00:31:27,990 --> 00:31:28,950 we just choose an address, 562 00:31:28,950 --> 00:31:31,770 which does convert nicely and also converts nicely to 563 00:31:31,770 --> 00:31:33,660 somewhere we control. 564 00:31:33,660 --> 00:31:38,660 And so we just choose this point here and we now got a SOC1. 565 00:31:38,850 --> 00:31:41,730 And the reason why we got a SOC1 is because it tried to 566 00:31:41,730 --> 00:31:43,140 run some code. 567 00:31:43,140 --> 00:31:47,640 We did try to run our EBCDIC translator to Debruijn String, 568 00:31:47,640 --> 00:31:50,103 and that's not real Z Arch Assembly. 569 00:31:52,170 --> 00:31:54,930 So all we need to do now is generate some 570 00:31:54,930 --> 00:31:58,620 real Z Arch Assembly and run it. 571 00:31:58,620 --> 00:32:03,620 So we take some shell code and all this is doing is just 572 00:32:05,828 --> 00:32:10,590 using SVC 35, which is right to operator. 573 00:32:10,590 --> 00:32:13,230 And this will just print out a nice little message that 574 00:32:13,230 --> 00:32:15,276 everyone can read on the SYS log. 575 00:32:15,276 --> 00:32:20,276 And it will say, "WTO", when it runs. 576 00:32:21,450 --> 00:32:25,560 And also something to note is that we've done a using star, 577 00:32:25,560 --> 00:32:27,120 comma R14. 578 00:32:27,120 --> 00:32:29,790 The reason why we do this is because we've returned on 579 00:32:29,790 --> 00:32:31,620 register 14. 580 00:32:31,620 --> 00:32:35,820 And that means that the program, when this is compiled, 581 00:32:35,820 --> 00:32:38,460 it needs to know where the base register is and that will 582 00:32:38,460 --> 00:32:39,960 then allow it to compile things. 583 00:32:39,960 --> 00:32:42,750 So it knows that, for example, when it does load address, 584 00:32:42,750 --> 00:32:47,263 register one message WTO, where that is and where that is. 585 00:32:50,610 --> 00:32:55,610 Okay, so now that we've got the code we wanna run, 586 00:32:55,890 --> 00:32:59,787 we now need to XOR the, 587 00:32:59,787 --> 00:33:04,470 XOR that code so that actually survives 588 00:33:04,470 --> 00:33:07,140 a ASCII to EBCDIC translation. 589 00:33:07,140 --> 00:33:08,553 And we just choose a, 590 00:33:09,600 --> 00:33:13,740 so we need to have a XOR key and a XOR shell code that 591 00:33:13,740 --> 00:33:14,763 both survives it. 592 00:33:15,630 --> 00:33:20,630 And luckily the XC instruction is a instruction which 593 00:33:20,880 --> 00:33:23,687 translates directly from ASCII to EBCDIC, 594 00:33:25,356 --> 00:33:26,189 so we don't have to deal with that, 595 00:33:26,189 --> 00:33:27,960 but that's just allows you to XOR that, 596 00:33:29,550 --> 00:33:32,940 the XC instruction allows you to XOR any two strings of, 597 00:33:32,940 --> 00:33:34,503 I think 255 length. 598 00:33:36,540 --> 00:33:41,540 So now that we've actually XOR-ed it, 599 00:33:42,570 --> 00:33:44,502 we now need to go through and I've, 600 00:33:44,502 --> 00:33:47,040 there's a Python script that we've written to 601 00:33:47,040 --> 00:33:48,300 do this automatically, 602 00:33:48,300 --> 00:33:52,440 but it will go through and find all of the bites that 603 00:33:52,440 --> 00:33:55,833 convert to the EBCDIC bites that we need. 604 00:33:57,060 --> 00:33:58,420 One thing to note is that 605 00:33:59,970 --> 00:34:02,550 not all translation tables will be the same. 606 00:34:02,550 --> 00:34:04,290 So one thing you can do is 607 00:34:04,290 --> 00:34:06,630 if you only use the printable characters. 608 00:34:06,630 --> 00:34:08,880 So like the alpha numerics, 609 00:34:08,880 --> 00:34:10,980 you know those ones are likely to be 610 00:34:10,980 --> 00:34:12,390 the same on every system. 611 00:34:12,390 --> 00:34:14,250 So that's what I would recommend using. 612 00:34:14,250 --> 00:34:19,250 So what you send over will only be ASCII characters, 613 00:34:20,190 --> 00:34:21,933 not ASCII, like alpha numerics. 614 00:34:24,450 --> 00:34:29,450 So then all you need to do is send that to the FTP server, 615 00:34:30,090 --> 00:34:32,250 with all of those addresses we've changed and 616 00:34:32,250 --> 00:34:33,570 the shell code added, 617 00:34:33,570 --> 00:34:36,360 and you'll see that it WTOs. 618 00:34:36,360 --> 00:34:38,610 The way to, 619 00:34:38,610 --> 00:34:41,220 so this is just a proof of concept. 620 00:34:41,220 --> 00:34:43,890 So you'd only rights to operator, 621 00:34:43,890 --> 00:34:47,700 but because the server is APF authorized, 622 00:34:47,700 --> 00:34:48,780 you could get it to do anything. 623 00:34:48,780 --> 00:34:50,310 So for example, 624 00:34:50,310 --> 00:34:52,743 you could spawn a reverse shell back to you, 625 00:34:54,300 --> 00:34:59,300 you could make it dump like some sensitive data sets. 626 00:34:59,520 --> 00:35:01,440 Yeah, you could crash the system, yeah. 627 00:35:01,440 --> 00:35:05,943 With APF authorized code execution, you can do anything. 628 00:35:09,034 --> 00:35:09,867 Okay. 629 00:35:09,867 --> 00:35:14,820 And we also hosted a workshop where 630 00:35:14,820 --> 00:35:16,740 you can actually do this yourself, 631 00:35:16,740 --> 00:35:20,970 which is another reason why I like doing this on NVS3.8J, 632 00:35:20,970 --> 00:35:24,810 because you can just create a Docker with a load of labs and 633 00:35:24,810 --> 00:35:25,860 just share it with people. 634 00:35:25,860 --> 00:35:27,933 So that's more interesting. 635 00:35:30,360 --> 00:35:33,180 And then got a number of references, 636 00:35:33,180 --> 00:35:35,003 so the, yeah. 637 00:35:42,690 --> 00:35:43,683 Any questions? 638 00:35:48,834 --> 00:35:51,834 (audience applauds) 639 00:36:03,330 --> 00:36:06,993 Do I just, do I, yeah? 640 00:36:08,004 --> 00:36:12,171 - [Audience Member] (indistinct). 641 00:36:27,960 --> 00:36:29,943 - No, it runs exactly the same. 642 00:36:35,032 --> 00:36:36,148 - Can you try to repeat the questions? 643 00:36:36,148 --> 00:36:36,993 - Oh, okay. 644 00:36:36,993 --> 00:36:37,860 Oh, okay, yeah. 645 00:36:37,860 --> 00:36:42,860 Yeah, if the emulator runs exactly the same as 646 00:36:43,903 --> 00:36:45,453 the heavy metal. 647 00:36:48,150 --> 00:36:49,653 Oh, yep? 648 00:36:51,390 --> 00:36:52,643 - [Audience Member] How long did it take you? 649 00:36:54,651 --> 00:36:58,330 - So I had a month long holiday and 650 00:36:59,731 --> 00:37:03,000 by the end of the holiday, 651 00:37:03,000 --> 00:37:04,770 I think I was less rested than I started, 652 00:37:04,770 --> 00:37:06,573 so about that long. 653 00:37:09,570 --> 00:37:11,135 Oh, yeah? 654 00:37:11,135 --> 00:37:15,302 - [Audience Member] (indistinct). 655 00:37:20,200 --> 00:37:21,650 And I wonder your experience, 656 00:37:22,545 --> 00:37:25,045 (indistinct)? 657 00:37:31,430 --> 00:37:34,290 - So most of the times main, oh yeah. 658 00:37:34,290 --> 00:37:37,920 The attack surface of a mainframe is mostly, 659 00:37:37,920 --> 00:37:40,260 it'd mostly be if someone already had access to 660 00:37:40,260 --> 00:37:44,689 the internal network, it's not really shared. 661 00:37:44,689 --> 00:37:47,310 There is some but not many. 662 00:37:47,310 --> 00:37:52,200 And a lot of, most of the attacks I've found are LPEs. 663 00:37:52,200 --> 00:37:54,540 So you need to have a user on the system to be able to 664 00:37:54,540 --> 00:37:55,950 escalate your privileges. 665 00:37:55,950 --> 00:37:57,510 But I do have a couple RCEs. 666 00:37:57,510 --> 00:37:59,653 So the ... 667 00:38:02,610 --> 00:38:03,443 No, I lost it. 668 00:38:06,179 --> 00:38:10,346 - [Audience Member] (indistinct). 669 00:38:13,200 --> 00:38:15,210 - Oh yeah, the, oh, 670 00:38:15,210 --> 00:38:18,240 the other thing about LPEs is that 671 00:38:18,240 --> 00:38:20,392 you think of a typical Linux box and you'd think, 672 00:38:20,392 --> 00:38:22,890 "I don't know how many users there would actually be." 673 00:38:22,890 --> 00:38:25,590 But on a typical mainframe box, 674 00:38:25,590 --> 00:38:27,690 there could be thousands of users. 675 00:38:27,690 --> 00:38:29,733 So an LPE is a little bit more, 676 00:38:30,660 --> 00:38:35,073 I'd say critical on a z/OS box than a Linux box. 677 00:38:45,360 --> 00:38:46,650 - So let's hear it for our speaker, again. 678 00:38:46,650 --> 00:38:48,625 Thanks, you did a great job. 679 00:38:48,625 --> 00:38:51,625 (audience applauds)