start	end	text
1100	5840	Hi, I'm Jake LaBelle, and my talk today is going to be on finding surrogate chains on a mainframe.
7120	10680	So, who am I? I'm a security consultant at F-Secure.
11760	14680	Technically associate, but sounds a bit shit, so...
15820	19960	I've been on a couple mainframe jobs, so I'm not an expert by any means.
20020	25200	I'm currently streaming from Basingstoke, UK, which is in Vegas, but what can you do?
25440	29400	And I was going to put a picture here, but just look to the right, and yep, there I am.
31380	37220	So, before I go into my tool that I've created, I'll just do a quick high-level introduction to ZOS,
37220	40360	which is the operating system that you find on most mainframes.
41400	49260	One of the major differences between Linux, Windows, and ZOS is that ZOS has datasets.
49440	55260	So, for example, here it's user01.rexlib, and one thing to know about it is it's a flat file system,
55260	60380	so there's no folders, but normally how it works is that you'll have your high-level qualifier
60440	69100	which is normally the owner first, so user01, and then .something, .something, blah, blah, blah.
69460	74700	And you have apostrophes around datasets. This indicates that it's an absolute path.
74700	81280	In all of my Gator program, I have apostrophes around every single dataset because it's just easier.
81680	88020	You can also have partitioned datasets, where user01.rexlib is the dataset,
88020	92580	but then you can have multiple members in that dataset. So, for example, in this one it would be hello.
92960	101940	And the picture below is just a picture of DSList, which shows all the datasets of a high-level qualifier of IBM user.
104620	111120	So, my program is mostly written in Rex, which is a scripting language like Python.
111460	114900	It has a couple slightly unique functions, though.
114900	119720	So, one of them is address, which lets you run a program in another program.
119720	129480	So, this is running listDSD in TSO, and the output of that you can store using something called outtrap,
129480	136740	which you will then put all the output of that TSO command into a stem variable, which is basically an array.
137880	142500	So, another language that's used is the JCL, which is a job control language.
142500	150540	It's a batch job, though, so when you submit a JCL, the JCL is then run at some point by the mainframe.
150760	157660	And on the first line of every JCL you have the job card, which has the title of the job and a couple of other parameters.
157660	165760	So, for example, this will notify the user after it's run, and it will also store it in the spool.
167600	175040	So, in my program, all of the JCLs that I have are embedded inside Rex scripts.
175360	180580	And so, this one, for example, it will queue all of the lines of the JCL.
180580	184100	It will then use outtrap to concatenate those lines and then submit them.
184140	192960	The reason why I use this in a Rex script is because you can then parse arguments easier, and you can then have a more dynamic JCL.
194700	203000	So, one of the major subsystems on ZOS is OMVS, and it's a Unix subsystem.
203000	207500	And it's kind of like the WSL Windows subsystem for Linux.
207500	213160	However, there's no segregation between the two parts.
213180	220320	So, there's no segregation between TSO and OMVS, TSO being the main part of where you log into the mainframe.
220320	225600	So, on TSO, you can run OMVS commands, and on OMVS, you can run TSO commands.
225600	229120	So, if you have access to one, you basically have access to the other.
229700	238440	And the security of OMVS, so for example, what would be slash etc slash sudoers, is managed by RACF.
238560	243040	And RACF is Resource Access Control Facility.
243040	257180	And this can handle different types of resources, so for example, datasets, surrogates, or as mentioned before, the OMVS resources.
257180	260320	So, for example, superuser would be in there.
261840	269380	So, each resource has an owner, and they have alter access, so basically complete access to the resource.
269380	277780	You can also set a UACC, which is how much access that just any random user has to the resource.
277780	280520	You can also permit other users to have access.
280520	282980	So, there's four different types of access you can give.
282980	289460	It's execute, read, update, and alter, and they do what they sound like they do.
289940	297100	One other special attribute you can give to a user is special.
297100	306460	Special means that you basically have alter access to every single resource, which you can think of as being like having roots.
307320	313380	One of the main classes in ZOS is surrogate, and there's a couple different types of these.
313380	326060	So, we have star.submit, so for example, userid.submit, so user01.submit would mean if you had read access to this, you could submit a JCL as user01.
326060	335320	There's also bpx.serve.userid, so for example, bpx.serve.user02 means you can run a su command as that user.
335800	342900	There's also dfh.start.userid, and this just means you can run a Kix transaction as that user.
342900	356840	I don't use dfh.start in my program, but maybe in the future.
358980	363740	So, one thing that you'll find on mainframes are surrogate chains.
363740	370340	The reason why these occur is because there's lots of users, and no one knows what all of them are for.
370340	377200	So, for example, I was added as a user on a pentest job, and 20 years later, someone's probably going to ask,
377200	380760	who is this Jake character, and why does he have access to these things?
380760	385860	No one's going to know, and no one's going to delete it, because maybe it'll break something.
386120	390120	And that also turns to the other thing, where mainframes have been running for decades.
390280	397820	It's one of their major selling factor, so the person who added me is probably going to be long gone before the next person even looks at me.
397820	405820	So, a surrogate chain is where, for example, user01 has read access to a surrogate class on user2,
405820	410560	and user2 has read access to a surrogate on user3.
411080	417060	So, in this case, user01 practically has access to everything that user3 has.
417460	423880	And the way you can list what access, what surrogates you have, you can run a command rlist surrogate star.
423880	433760	However, RACF has a thing where you can only see the protections on a RACF that you have at least read for.
433760	443040	So, in this case, user01 would not be able to see that user2 has a read on a surrogate on user3.
443280	448240	The other problem is that star.submit is a batch job.
448240	462140	So, let's say you wanted to run a REC script that ran the JCL from user1 as a surrogate on user2,
462140	466420	and then wanted to, from user2, run a JCL to user3.
466420	471920	You can't just run that in one program because it's using a JCL, which, again, is a batch job.
471920	476240	So, what you could do is you could manually submit reverse shells one at a time.
476240	483140	So, you'd, as user1, find out that you had a user2 surrogate, then you would submit a reverse shell for user2.
483140	488580	Then, once you're as user2, you'd list all your surrogates again, and then you'd submit a reverse shell for user3.
488700	494600	However, this takes a long time, and there's a lot of users, so this might not even be feasible.
495680	500200	Another thing you could do is you could just use a user which has read access to all the resources.
500200	503960	So, for example, a special account or an auditor account.
504580	509740	Auditor doesn't really... they don't really have read access to these, but they basically do.
511900	516340	Then, you could also then use this to find all the surrogate chains.
516340	519780	The only problem with this is that you're not going to get a special account.
519780	526620	You're definitely not going to get a special account on a pen test, and you probably won't get an auditor account on a pen test either.
527900	537160	So, I created a tool. Here's the GitHub link to it, and it allows you to find and exploit surrogate chains.
537380	541620	So, the first thing you do with the tool is you run begin.reqs. It gets all the output datasets ready.
541620	549700	It gets the Unix file ready, and it adds the current user that you're running it from to the path, and it starts geo.reqs.
550520	558920	geo.reqs gets the path that it currently is at, so when you first run it, it would just be the original user.
559000	565380	If it's special, if your user that you have is special, it will just stop, because if you have special, you've already won.
565700	568920	It will then run plugins.reqs, which I'll explain later.
569080	575020	It will list all the surrogates that you have read access to, and then it checks that those surrogates haven't been visited yet.
575020	581560	The reason why I had to add this is because I didn't want to have to deal with cycles, and this was the quickest and easiest way to deal with that.
581660	588980	So, you won't actually get the whole, I guess, surrogate network, but you will get a chain through them.
590160	599120	If it sees that it's a star.submit resource, it will run subm.reqs, and if it sees that it's a bpx.sub.star resource, it will run unixm.reqs.
599120	607340	So, subm.reqs just submits a JCL as the surrogate user, which then runs gator.reqs, so then it will continue it on.
608080	611240	Unixm.reqs is a JCL which just runs gator.
611240	626340	It's moved into OMVS with begin.reqs to slash temp slash unixm, and then gator calls it with bpx batch, with which you run OMVS commands in TSO, and then you do su to that target user.
626340	631640	So, plugins.reqs is a list of req scripts to run on each user.
634380	640600	There's a number of enumeration scripts you can run. I have three that I have set up already.
640740	651080	One of them just lists the user, so this will tell you if they have special, if they have operations, what groups they're connected to, those types of things.
652780	661160	I also have one which will just list your access to all of the RACF databases.
661160	667100	It's unlikely you'll have anything other than none for this, but, eh, might as well test.
667100	674940	If you have read access, it's really good. It lets you unload the database so you can see all the things in the RACF database. Really useful.
674940	686160	If you have update or alter, then you can just put yourself in as special, and I have a tool to just write yourself in, but, yeah, they're very unlikely, but if it does happen, hit the jackpot.
686940	693160	The other one is it will search all of the APF libraries to see what access you have to those.
693160	698040	You can think of APF libraries as kind of like setguid libraries in Unix.
698040	705720	It's not really, but if you have update or alter, you can get special, and there's tools out there to do that.
706700	722600	Oh, and also, if you have any other scripts you want to add, it's fairly easy to just, it's fairly extensible, just add your own REC script in, and, like, for example, if you have just a Linux script that you have that you can use, you can quickly add that to there.
723820	744640	So, to test to see that the program was working properly, I, using an emulated ZOS, created a thousand users, then randomly assigned a couple operators and a couple special users, added a couple of surrogates of each type to each user, and then ran Gator, the test script to generate all of these users on GitHub as well.
744640	764780	So, using the output of all the paths that were generated and also the list user command, so here you can see the large squares are operators and the big star is special, shows you all the paths to get to these users.
764960	770900	If anyone can think of a better way to show a thousand nodes on a graph, then, yeah, that'd be helpful.
771740	796940	I also created a shell macro, so from the user that you ran the Gator from, you can pick any user that's in the path, the surrogate chain, and it will run shell B, that user, it will then keep submitting a JCL, continuously passing on how far along in the target it is, how far along in the path to the target is,
796940	802480	and at the end it will submit a catso shell, it's like an interpreter, here's the GitHub link to it by mainframed.
804300	812300	I've also just created a bash script which will quickly upload all the rec scripts, it's just quick to set that up.
813280	819660	And yeah, that's my tool, and I'll do a quick thing on if you want to get into mainframes yourself.
819660	830260	So probably the easiest way is with TK4-, it's based on a 1980s mainframe, MVS 3.8J, it runs on a Raspberry Pi, which is pretty cool.
830580	843500	Everything is open source and public domain, pretty cool again. Here's the link to download it, and there's a user guide to just get started, and yeah, here's a picture of it, again, pretty cool.
846200	856400	And on there you can install two fairly important things, so you can get Kix, which is a Kix clone, and there's a Moshix guide, I've put the YouTube link to it.
856400	864720	And Kix is like web servers, before web servers were cool, so you can test your COBOL scripting.
865620	877240	And Rex is just a backported thing that lets you run rec scripts, again, here's the Moshix guide to get it installed.
877240	885080	If you can't be bothered to get these installed, I have one with these already installed on my GitHub. TK4-base is what I called it.
885860	896280	Another tool to get started on mainframes is Hercules, it's a QPublic license, it's a mainframe emulator, and it's what TK4 uses to run.
896860	908120	Now there is an old version of ZOS version 1.10 online, but piracy is bad, so don't do that.
908120	919060	But if you do end up getting a ZOS version, there's a GitHub link to mainframes labs, and they're pretty good to get started.
920320	927960	And there's a Mattermost community that's fairly good to answer any questions.
927960	934900	If you want to ask me any questions, my username is Tadasu, so drop me a message on there and I'll answer.
934900	940900	And that's my talk done. Are there any questions?
