Mainframe Surrogat Chains
CC Attribution 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Labelle, Jake
z/OS allows a user to submit a job as another user without a password with the surrogat class. However, z/OS systems often have hundreds of thousands of users and have been running for decades. This means that it is very likely that from a low priv user there is a surrogat chain that will give you special (z/OS' root). RACF (z/OS' Security), does not allow users to view the security of resources to which they do not have access. This means that manually enumerating a chain required you to submit a reverse shell each time you wanted to move up the chain. This will take a long time with 200k users. Gator (my tool), submits a batch job that will call a REXX program which will output the user's privs and the current surrogat chain of that user. It will then list all of that user’s surrogat privs, and call the same batch job as before, but running as those users. Gator also provides a macro that will generate a CATSO (similar to a meterpreter shell), for any of the users in the surrogat chain. Gator can also be exported to a GraphVis python program, which will display the users information and chain as a network of nodes.
 Hi, I'm Jake LaBelle and my talk today is going to be on finding surrogate chains on a mainframe. So who am I? I'm a security consultant at Fsecure. Technically associate but sounds a bit shit so I've been on a couple mainframe jobs so not expert by any means. I'm currently streaming from Bezingstoke UK. Wish you was in Vegas but what can you do? I was going to put a picture here but just look to the right and there I am. So before I go into my tool that I've created I'll just do a quick high level introduction to ZOS which is the operating system that you find on most mainframes. One of the major difference between Linux Windows and ZOS is that ZOS has data sets. So for example here it's user1.rexlib and one thing to know about it is it's a flat file system. So there's no folders but normally how it works is that you'll have your high level qualifier which is normally the owner first so user1 which would be and then dot something dot something value bar. And you have apostrophes around data sets. This indicates that it's an absolute path. In all of my Gala program the I have apostrophes around every single data set because it's just easier. You can also have partition data sets where so user1.rexlib is the data set but then you can have multiple members in that data set so for example in this one it'd be hello. And the picture below is just a picture of DSList which shows all the data sets of a high level qualifier of IBM user. So my program is mostly written in rex which is a scripting language like Python. Has a couple slightly unique functions though so one of them is address which lets you run a program in another program. So this is running list dsd in TSO and the output of that you can store using something called outtrap which you will then put all the output of that TSO command into a stem variable which is basically an array. So another language that's used is the JCL which is a job control language. It's a batch job though so when you submit a JCL the JCL is then run at some point by the mainframe. 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. So for example this will notify the user after it's run and it will also store it in the spool. So in my program all of the JCLs that I have are embedded inside rex scripts and so this one for example it will queue all of the lines of the JCL. It will then use outtrap to concatenate those lines and then submit them. The reason why I use this in a rex script is because you can then pass arguments easier and you can then have a more dynamic JCL. So one of the major subsystems on ZOS is OMVS and it's a Unix subsystem and it's kind of like the WSL Windows subsystem for Linux. However there's no segregation between the two pots. So there's no segregation between TSO and NVS, TSO being the main part of where you log into the mainframe. So on TSO you can run OMVS commands and on OMVS you can run TSO commands. So if you have access to one you basically have access to the other. And the security of OMVS, so for example what would be slash etc slash sudoers is managed by rackf. And rackf is resource access control facility and this can handle different type of resources so for example datasets, surrogates or as mentioned before, the sudo, the OMVS resources, for example super user would be in there. So each resource has an owner and they have alter access so basically complete access to the resource. You can also set a UACC which is how much access that just any random user has to the resource. You can also permit other users to have access so there's four different types of access you can give. It's execute, read, update and alter and they do what they sound like they do. One other special attribute you can give to a user is special. Special means that you basically have alter access to every single resource which you can think of as being like having roots. One of the main classes in ZOS is surrogate and there's a couple different types of these so we have star.submit so for example userid.submit so user1.submit would mean if you had read access to this you could submit a jcl as that as user1. There's also bpx.sub.userid so for example bpx.sub.user2 means you can run a sucommand as that user. There's also dfh.start.userid and this just means you can run a kicks transaction as that user. I don't use dfh.start in my program but it's maybe in the future. One thing that you'll find on mainframes are surrogate chains and the reason why these occur is because there's lots of users and no one knows what all of them are for. So for example I was added as a user on a pentest job and 20 years later someone's probably going to ask who is this Jake character and why does he have access to these things. No one's going to know and no one's going to delete it because maybe it will break something. Now also it's the other thing where mainframes have been running for decades. 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. So a surrogate chain is where for example user1 has read access to a surrogate class on user2 and user2 has read access to a surrogate on user3. So in this case user1 practically has access to everything that user3 has and the way you can list or access what surrogates you have you can run a command rlist surrogate star. However rackf has a thing where you can only see the protections on a rackf that you have at least read for. So in this case user1 would not be able to see that user2 has a read on a surrogate on user3. The other problem is that star.submit is a batch job so let's say you wanted to run a rex script that ran the jcl from user1 to as a surrogate on user2 and then wanted to run a jcl from user2 to user3 you can't just run that in one program because it's using a jcl which again it's a batch job. So what you could do is you could manually submit reverse shells one at a time so you would as user1 find out that you had a user2 surrogate then you would submit a reverse shell for user2 then once you're as user2 you would list all your surrogates again and then you would submit a reverse shell for user3. However this takes a long time and there's a lot of users so this might not even be feasible. Another thing you could do is you could just use a user which has read access to all the resources so for example a special account or an auditor account. They don't really have read access to these but they basically do. Then you could also then use this to find all the surrogate chains. The only problem with this is that 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. So I created a tool, here's the GitHub link to it and it allows you to find and exploit surrogate chains. The first thing you do with the tool is you run begin.rex, it gets all the output data sets ready, it gets the Unix file ready and it adds the current user that you're running it from to the path and it starts geodotrex. Geodotrex gets the path that it currently is at so when you first run it it would just be just the original user. If it's special, if you're user that you have a special it will just stop because if you have special you've already won. It will then run plugins.rex which I'll explain later. It will list all the surrogates that you have read access to and it checks that those surrogates haven't been visited yet. 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. So you won't actually get the whole surrogate network but you will get a chain of through them. If it sees that it's a star.submit resource it will run subim.rex and if it sees that it's a bpx.srb.star resource it will run unixm.rex. So subim.rex just submits a jcl as the surrogate user which then runs geodotrex so then it will continue it on. Unixm.rex is a jcl which just runs geodotrex. It's moved into omvs with begin.rex to slash temp slash unixm and then geodotrex calls it with bpxbatch which you run omvs commands in TSO and then you do su to that target user. So plugins.rex is a list of rex scripts to run on each user. There's a number of enumeration scripts you can run. I have three that I have set up already. 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. I also have one which will just list your access to all of the rackf databases. It's unlikely you'll have anything other than none for this but might as well test. If you have read access it's really good. It lets you unload the database so you can see all the things in the rackf database. Really useful. If you have updated alter then you can just put yourself in a special and I have a tool to just write yourself in but they're very unlikely but if it does happen hit the jackpot. The other one is it will search all of the apf libraries to see what access you have to those. You can think of apf libraries as kind of like setguid libraries in unix. It's not really but if you have updated alter you can get special and there's tools out there to do that. 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 rex script in and like for example if you have a linux script that you have that you can use you can quickly add that to there. To test to see that the program was working properly I, using an emulated ZOS, created 1000 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. 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. If you anyone can think of a better way to show 1000 nodes on a graph then yeah that'd be helpful. 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 run shell b that user it will then keep submitting a jcl continuously passing on how far along in the path to the target it is and at the end it will submit a katsos shell it's like a meterpreter here's the github link to it by mainframed. I've also just created a bash script which will quickly upload all the rex scripts it's just quick to set that up. And yeah that's my tool and I'll do a quick thing on if you want to get into mainframes yourself so one of the 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 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 and on there you can install two fairly important things you can get kicks which is a kicks clone and there's a moshics guide I've put the youtube link to it and kicks is like web servers before web servers were cool so you can test your cobalt scripting and rex is just a back ported thing that lets you run rex scripts again here's the moshics guide to get it installed if you can't be able to get these installed I have a one with these already installed on my github tk4 base that's what I called it. Another tool to get yourself started on mainframes is Hercules it's a qpublic license it's a mainframe emulator and it's what tk4 uses to run. Now there is an old version of zos version 1.10 online but piracy is bad so don't do that but if you do end up getting a zos version there's a github link to mainframes lamps and they're pretty good to get started. And there's a matamost community that's fairly good to answer any questions if you want to ask me any questions my username is todassu so yeah drop me a message on there and I'll answer. And that's my talk done. Are there any questions?
 Hi, I'm Jake LaBelle and my talk today is going to be on finding surrogate chains on  a mainframe.  So who am I?  I'm a security consultant at Fsecure.  Technically associate but sounds a bit shit so I've been on a couple mainframe jobs so  not expert by any means.  I'm currently streaming from Bezingstoke UK.  Wish you was in Vegas but what can you do?  I was going to put a picture here but just look to the right and there I am.  So before I go into my tool that I've created I'll just do a quick high level introduction  to ZOS which is the operating system that you find on most mainframes.  One of the major difference between Linux Windows and ZOS is that ZOS has data sets.  So for example here it's user1.rexlib and one thing to know about it is it's a flat  file system.  So there's no folders but normally how it works is that you'll have your high level  qualifier which is normally the owner first so user1 which would be and then dot something  dot something value bar.  And you have apostrophes around data sets.  This indicates that it's an absolute path.  In all of my Gala program the I have apostrophes around every single data set because it's  just easier.  You can also have partition data sets where so user1.rexlib is the data set but then you  can have multiple members in that data set so for example in this one it'd be hello.  And the picture below is just a picture of DSList which shows all the data sets of a  high level qualifier of IBM user.  So my program is mostly written in rex which is a scripting language like Python.  Has a couple slightly unique functions though so one of them is address which lets you run  a program in another program.  So this is running list dsd in TSO and the output of that you can store using something  called outtrap which you will then put all the output of that TSO command into a stem  variable which is basically an array.  So another language that's used is the JCL which is a job control language.  It's a batch job though so when you submit a JCL the JCL is then run at some point by  the mainframe.  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.  So for example this will notify the user after it's run and it will also store it in the  spool.  So in my program all of the JCLs that I have are embedded inside rex scripts and so this  one for example it will queue all of the lines of the JCL.  It will then use outtrap to concatenate those lines and then submit them.  The reason why I use this in a rex script is because you can then pass arguments easier  and you can then have a more dynamic JCL.  So one of the major subsystems on ZOS is OMVS and it's a Unix subsystem and it's kind of  like the WSL Windows subsystem for Linux.  However there's no segregation between the two pots.  So there's no segregation between TSO and NVS, TSO being the main part of where you  log into the mainframe.  So on TSO you can run OMVS commands and on OMVS you can run TSO commands.  So if you have access to one you basically have access to the other.  And the security of OMVS, so for example what would be slash etc slash sudoers is managed  by rackf.  And rackf is resource access control facility and this can handle different type of resources  so for example datasets, surrogates or as mentioned before, the sudo, the OMVS resources,  for example super user would be in there.  So each resource has an owner and they have alter access so basically complete access  to the resource.  You can also set a UACC which is how much access that just any random user has to the  resource.  You can also permit other users to have access so there's four different types of access  you can give.  It's execute, read, update and alter and they do what they sound like they do.  One other special attribute you can give to a user is special.  Special means that you basically have alter access to every single resource which you  can think of as being like having roots.  One of the main classes in ZOS is surrogate and there's a couple different types of these  so we have star.submit so for example userid.submit so user1.submit would mean if you had read  access to this you could submit a jcl as that as user1.  There's also bpx.sub.userid so for example bpx.sub.user2 means you can run a sucommand  as that user.  There's also dfh.start.userid and this just means you can run a kicks transaction as that  user.  I don't use dfh.start in my program but it's maybe in the future.  One thing that you'll find on mainframes are surrogate chains and the reason why these  occur is because there's lots of users and no one knows what all of them are for.  So for example I was added as a user on a pentest job and 20 years later someone's probably  going to ask who is this Jake character and why does he have access to these things.  No one's going to know and no one's going to delete it because maybe it will break something.  Now also it's the other thing where mainframes have been running for decades.  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.  So a surrogate chain is where for example user1 has read access to a surrogate class  on user2 and user2 has read access to a surrogate on user3.  So in this case user1 practically has access to everything that user3 has and the way you  can list or access what surrogates you have you can run a command rlist surrogate star.  However rackf has a thing where you can only see the protections on a rackf that you have  at least read for.  So in this case user1 would not be able to see that user2 has a read on a surrogate on  user3.  The other problem is that star.submit is a batch job so let's say you wanted to run  a rex script that ran the jcl from user1 to as a surrogate on user2 and then wanted to  run a jcl from user2 to user3 you can't just run that in one program because it's using  a jcl which again it's a batch job.  So what you could do is you could manually submit reverse shells one at a time so you  would as user1 find out that you had a user2 surrogate then you would submit a reverse  shell for user2 then once you're as user2 you would list all your surrogates again and  then you would submit a reverse shell for user3.  However this takes a long time and there's a lot of users so this might not even be feasible.  Another thing you could do is you could just use a user which has read access to all the  resources so for example a special account or an auditor account.  They don't really have read access to these but they basically do.  Then you could also then use this to find all the surrogate chains.  The only problem with this is that 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.  So I created a tool, here's the GitHub link to it and it allows you to find and exploit  surrogate chains.  The first thing you do with the tool is you run begin.rex, it gets all the output data  sets ready, it gets the Unix file ready and it adds the current user that you're running  it from to the path and it starts geodotrex.  Geodotrex gets the path that it currently is at so when you first run it it would just  be just the original user.  If it's special, if you're user that you have a special it will just stop because if you  have special you've already won.  It will then run plugins.rex which I'll explain later.  It will list all the surrogates that you have read access to and it checks that those surrogates  haven't been visited yet.  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.  So you won't actually get the whole surrogate network but you will get a chain of through  them.  If it sees that it's a star.submit resource it will run subim.rex and if it sees that  it's a bpx.srb.star resource it will run unixm.rex.  So subim.rex just submits a jcl as the surrogate user which then runs geodotrex so then it  will continue it on.  Unixm.rex is a jcl which just runs geodotrex.  It's moved into omvs with begin.rex to slash temp slash unixm and then geodotrex calls  it with bpxbatch which you run omvs commands in TSO and then you do su to that target user.  So plugins.rex is a list of rex scripts to run on each user.  There's a number of enumeration scripts you can run.  I have three that I have set up already.  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.  I also have one which will just list your access to all of the rackf databases.  It's unlikely you'll have anything other than none for this but might as well test.  If you have read access it's really good.  It lets you unload the database so you can see all the things in the rackf database.  Really useful.  If you have updated alter then you can just put yourself in a special and I have a tool  to just write yourself in but they're very unlikely but if it does happen hit the jackpot.  The other one is it will search all of the apf libraries to see what access you have  to those.  You can think of apf libraries as kind of like setguid libraries in unix.  It's not really but if you have updated alter you can get special and there's tools out  there to do that.  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 rex script in and like for example if you have a linux script  that you have that you can use you can quickly add that to there.  To test to see that the program was working properly I, using an emulated ZOS, created  1000 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.  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.  If you anyone can think of a better way to show 1000 nodes on a graph then yeah that'd  be helpful.  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 run shell b that user it will then  keep submitting a jcl continuously passing on how far along in the path to the target  it is and at the end it will submit a katsos shell it's like a meterpreter here's the  github link to it by mainframed.  I've also just created a bash script which will quickly upload all the rex scripts it's  just quick to set that up.  And yeah that's my tool and I'll do a quick thing on if you want to get into mainframes  yourself so one of the 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 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 and on there you can  install two fairly important things you can get kicks which is a kicks clone and there's  a moshics guide I've put the youtube link to it and kicks is like web servers before  web servers were cool so you can test your cobalt scripting and rex is just a back ported  thing that lets you run rex scripts again here's the moshics guide to get it installed  if you can't be able to get these installed I have a one with these already installed  on my github tk4 base that's what I called it.  Another tool to get yourself started on mainframes is Hercules it's a qpublic license it's a mainframe  emulator and it's what tk4 uses to run.  Now there is an old version of zos version 1.10 online but piracy is bad so don't do  that but if you do end up getting a zos version there's a github link to mainframes lamps  and they're pretty good to get started.  And there's a matamost community that's fairly good to answer any questions if you want to  ask me any questions my username is todassu so yeah drop me a message on there and I'll  answer.  And that's my talk done.  Are there any questions?
DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_0_155.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_156_1019.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_1020_2603.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_2604_13427.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_13428_13727.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_13728_14975.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_14976_17639.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_17640_17699.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_17700_18071.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_18072_18611.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_18612_19271.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_19272_20075.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_20076_20303.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_20304_20999.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_21000_21107.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_21108_22127.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_22128_22979.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_22980_23375.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_23376_23435.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_23436_23483.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_23484_23531.png DEF_CON_Safe_Mode_-_Jake_Labelle_-_Getting_Shells__KUND0KllCKc_23532_23546.png