PwnShop [easy] - HackTheBox Pwn Challenge

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we're going to take a look at the pawn shop challenge on hack the box it's an easy phone challenge and the description says we just opened a phone shop time to pawn all the things uh just before i get started note to youtube this is a challenge it's on a challenge website i'm not hacking anything i'm trying to teach people cyber security techniques i'm not uh encouraging any illegal activities um for some reason youtube over the past week have given me two warnings removed uh videos for which i have i have demonstrations that i provided at university to undergrad and master students on how to use metasploit in one case and in another case on a ctf that i put together which was an ubuntu vm and i created a ctf where there's three ways to get user three ways to get root and it was just me walking through the the the ctf that i've i've actually provided to computer science and um cyber security students before so and it was also private as well it wasn't even a public video so yeah it um what you what you might also notice is that if unless youtube have amended this the chapters don't work in my videos either so since they gave me a warning which is apparently a permanent warning on the account and if you get three strikes you're banned for life um then since they did that the chapters no longer work so you might have to go down to the description to look at the time stamps if you want to skip through to different chapters for example skip through this run about um youtube attacking security researchers anyway uh ran over let's download these files and try to solve the challenge so copy this over to local directory and let's go and do some basic file checks okay so hopefully you've watched the previous phone challenges before this you know how this goes we check the file type we see the 64-bit lsb executable it's dynamically linked so it's going to be calling out to lib c it's uh stripped so we're not going to be able to get the function names and things like that we're not going to see where the main the main function and pi is enabled so i think a couple of the challenges we've done so far some of the box prone challenges we've been through have had pi enabled let's run check sec here as well and just confirm what's enabled run through some updates um so there's no canaries nx is enabled so the goal isn't going to be to inject shell code onto the stack the goal is likely going to be to do some rock chains and pi is enabled as well so this means that whenever the binary is loaded it's going to load into different locations each time so we're going to need to leak the address in order to then find offsets and things like that so i can't remember exactly which challenges we've used this on so far it's been it's been a couple of weeks since i recorded i think the last phone challenge but um although these are coming out daily uh they've been recorded over time so let's uh let's run the program and see what's actually going on we could also run strings forgot that we could run strings and have a look through here but because it's stripped we're not going to see some of the um symbols we can get an idea what's going on with the text but let's just go ahead and run it instead and see what the functionality is like so we'll do chmod make it executable we'll run it and we'll see here we've got three different options we can buy we can sell we can exit so let's check our exit first of all you can see it just exits check out buy and it says sorry we're currently we're we aren't selling right now you can place a request and ask us some details let's put in some details all right it wasn't just took some details of us didn't print anything back let's go to sell what do you wish to sell and let's just do the same let's see if there's some kind of buffer overflow here um how much do you want for it okay and it comes back what and it repeats some of our query but it but not all of it you can see here it's actually failed to print some of these characters uh and then it says the best we can do is 1337. let's go back and run that again and we'll put something in here how much you want for it we'll do 1337 and then they say okay that sounds good leave it here so i can ask my guys to take a look so there might be a buffer overflow here as well um it doesn't look like it it's just our response is overflowed and gone through as answers here okay let's let's check the buy option again i'm going to put in a longer request here and we got a segmentation full in that case we got segmentation full but two characters that we'd entered over spilled over into the into our command line as well so there is a buffer overflows buffer overflow on the by and the cell appears to be leaking something we're not able to display this we're going to want to have a look at this in hex and see if this is an address to something if it is we can go and have a look in gdb while the program's running and see what what does it what does it point to so dynamic analysis some basic dynamic analysis they're done we could run through it with ltrace as well but let's um let's open this with geardraw and do some static analysis on the decompiled code so we will create a new project call it pawnshop and then we can import the file up some stuff from leak test uh which was i guess the last video then it's been a while um well it's probably not been actually that long i can't even remember it's just been a lot going on okay so open this up i just hit ok to all the default stuff here and then uh analyze yes analyze okay and then we get into our code here so we know that it's not going to take us to a main function we don't want to have a main function here because because it's stripped we can see here the lib c start main but um so how do we get to our functions uh functions of interest well we can go through and we can start having a look around there you can see the first one i happen to have clicked on has taken us to some code that we recognize because this these are some of the responses and prompts that we got but um sometimes you're gonna have really big programs where there's gonna be a lot of functions maybe there's some obfuscation and stuff done so really a better way to do this would have been to go to the entry function and then have a look to see what's actually being called here and we can go in and see what's being called the first thing that's being called is this main menu so we start the main function we have our options here so we have if it was option one that was the buy buy option so it says sorry we aren't selling now and hit here so we have the buffer of 72 and then it's reading in um 80 so there's our overflow but that's not very much room so although we can't inject shell code anyway we're not going to be able to inject much in the way of a rock chain to that so it's likely we'll need to pivot the stack to give ourselves some more space so if you have seen the rope emporium series that i did a while ago i believe we we did some similar stuff in there with pivoting so let's go back and have a look at the second function as well the third function it was just an exit so let's have a look so this is our cell function where we asked what we want to sell and how much we want for it and if we put in 1337 remember that it asked for our details and then it's obviously going to take in the details here otherwise it appeared to leak out some kind of address whenever we put in a long number of like 10 ones or something like that so let's try and map out the variables that we have here to the code and see what's going on if there's any overflows or what's going on with the the leaking of addresses so if we work through this in order we have a local 20 variable which is we can see here is a pointer and it's been assigned this data location so this is in the bss section and there's there's nothing here it's just all empty we then it prints out what you wish to sell it has some kind of a loop here i'm not exactly sure what it's doing and then it reads the input offers into this stack so it's reading in we can see here one f which is um 31 in decimal and it's being read into the stack which is eight but if we have a look at the type there it's undefined it's actually double word so that'll be 32 and then so there's no issues there we have 31 and then room for our null terminator as well but then we have this section where it asks us how much we want for it and this is where we found that if we put in like 10 ones it was printing out some funny looking characters so if you look here this is being read into local 28 which is right here and this is again eight bytes it's reading in eight bytes as well which can allow us actually to overwrite the null terminator and spill over through that variable to what's next on the stack so if we see that um if we would have put in 1337 we have another loop kind of like we had here and then it reads in the data from us it reads in 64 bytes and that's being read to local 20 so that's actually that memory look the pointer to this memory location but the local 28 then if we were to overwrite that null terminator we can actually get into the next value on the stack which will be this local 20 which is important because we're trying because pi is enabled and this is and you can see here this address is going to load up these are actually offsets to the address which is going to be different every time the program loads so we need to whenever we run the program we need to then find what's the base address of the program so that we can then use these offsets to get to different drop gadgets or whatever we whatever we need different offsets so let's go and play around with the application again and see uh if we can kind of match up the size that we had there that eight bytes with this eight bytes are being read in so if we go back let me minimize this so you can see it a little better if we go back here and run the program we'll go straight to cell and just put in whatever and then let's try and do one two three four five six seven so we print that you see we get this the funny looking characters there let's do that again go back cell let's not let me go back to cell okay well let's not let me do anything let's run that again we'll go back to cell and this time we'll do eight one two three four one two three four oh sorry that was the wrong thing and again we print out some values okay if i go back so it doesn't actually let me go back after that let's go back and do this again and do six this time one two three four five six and in this case it doesn't print anything out so it's as soon as we get to seven that it's actually printing that out again we can go back and say one two three four five six seven and you can see there it's actually printing that out on a new line so we want to go and try and um capture this you capture this in python or something we'll go and set up a pwn tool script anyway and capture this and try and convert it to a memory address and then we'll go and look in gdb and see what does actually translate to where's that pointed to but what we would hope it's going to point to is the next value on the stack which is actually this memory location and because we know here that this memory location is at this offset we can then subtract this offset to get to our the base of our application so we're going to go and open up gdb here open up phone debug gdb dash phone debug and pass in pawnshop very quickly i'll mention as usual if you're in here you can run help get a list of commands you can say help aliases or something else i don't have any a-listers like help data and you'll get more commands you can keep going through like that you can also type phone debug and you'll get a list of different plugins and things that you can call so we could call radar for example from in here if i can just do r2 and we could do aaa to analyze afl to look at the functions here and then we could go and disassemble this in here and this actually gives us a main method even though it's it's fast it's detected essentially the main method even though we don't have and you can see we have our offsets here and stuff as well so if we want to be fill if we want to fill in our prone tool scripts later it's quite easy to go and grab offsets and things in here we can do s sim uh no s we'll do s main not man s main and then pdf if you want to disassemble you can do control and v shift and v ctrl v or maybe you can't do it from here to skip into visual mode you can do that from outside of uh gdb um anyway let's go back to our phone debug what we could do is it's been a while since we've done it i think is look for an offset let's do cyclic uh a hundred we're not really not gonna need a hundred because we know that that we only had eight was it eight bytes it might have been eight um d were uh let's let's find out here we'll find out so let's run i've copied the cyclic pattern we've run the program we're gonna do buy and says yeah we're not selling right now we're going to paste in this long pattern and it comes back and it's failed it's a segment it's got a segmentation fault like we'd expect it doesn't have our cyclic pattern in the rip because 64-bit doesn't won't load it so we have to take the value out of the rsp here and then we can do cyclic l to look for that and it says it must be four bytes okay oh sorry we want the first four bytes what am i doing uh cyclic l we look for the first four bytes we find it's 72 bytes in so essentially what we what we knew here anyway let's let me go back um entry let's go into our function we've got our so if we hit one it's going to be this buy and we know that we had 72 bytes here and right here it's reading in 80. you can see here the 50 we highlight that we see it's reading in 80 so it's actually we've only got the eight bytes available which is going to be just enough for us to jump to some somewhere in memory so essentially what we're going to need to do there is create some more space or pivot the stack and we'll look into we'll look into that shortly but that's our offset calculated anyway one other thing i'll mention here is in phone debug let me minimize this so you can see a bit better we can do pi base so whenever the program loads although we need to actually leak the pi base because we're going to be running this against the server so we need the we need the value to be leaked back to us because we can't just open up gdb and do and do this but locally whenever we're testing this out we can just run pi base and that'll tell us this is the base of the binary we can also do you can search here pi base let me do pi base dash help and you'll see that actually if we pass in an offset it will give us uh whatever offset we're looking for so for example if there was something in here we wanted to jump to i could just copy the offset and we could say i'm missing a c there but we could say pi base 0x 7c and this will okay this will give us the offset of that i think because of whatever i've whatever i've picked there it's not really given a this is something like outside of the code yeah i'm not even in the phone shop function that's why let me see let me go back all right i'll do this again this is the what you want to do so let's copy this so what you want to do um string if i go here and do pi base and give the offset of that oh it's beyond the memory pages okay um maybe it's because the we've already crashed the program let me run this again uh let's set a we can't break main here info functions uh what i'll do i'll open up radar because we saw that whenever we checked the functions here it gave us the main so let's do that instead let's copy this i'll exit that again and we'll say what we can actually do here rather than even doing the pi base we can do break rva so let me do break rva help and you'll see here break rva this will break the basically the offset here from the pi base so we can pass in break rva 0x and that is the offset that we just found to main in red air uh we can do that the program's not being run so it's not going to allow us to do that so i'll exit that we're already in the main method so i can't do that now probably but well you can set the breakpoint anyway um we can do pi base as well this would have basically done the same sort of thing if we did pi base and then 0x and that address and that's just basically going to calculate what is the offset so it's just if you're working jumping between pawn tools and gdb it can be handy to calculate offsets on the fly if you need to um okay i hope that didn't cause any confusion let's go ahead and create our pawn tools script and start automating some of this so we'll copy the prone tools template as usual pro tools template we'll just call it exploit dot py for now be careful calling things i was going to call it pone dot py there but if you import in like the pwn library and you can have problems so just be careful the name and of things and let's open this up codium and start to make our initial changes so just a little bit of a refresher for anybody who's watched the previous poem videos before this which hopefully you have or for anybody that's new and hasn't watched those i recommend you go back and watch them but if you if you haven't and don't know the drill here this template uh particularly if if you're new to these challenges might look a little bit daunted most of this is just you just leave this as it is we just have some functions here for starting this depending if we want it to run remotely if we want to debug in gdb if we do want to debug in gdb we can insert breakpoints and things here we can also if we want to let's say get the pi base we could put that in there as well just any command that you can run in gdb we can we can run here basically we could do our brake rvas as well to set that to break um and get get our offset from radar or from uh gear draw wherever we have a find ip function here which will find our buffer overflow so let's i'm going to comment some of this out in fact take some of this out all together we're not going to be writing the payload to file we're going to be getting a shell we're not going to be getting a flag so let's change this and just say got shell and we're gonna do io.interactive and i'll just take this out of here for now as well we'll leave in our sample payload payload structure so this is gonna start the program but before we start the program we're actually going to send this off here to get a to find out what how many bytes do we need to overwrite to get our overwrite the return address so we know that it was we need to go to the buy function let's go back here we go to the buy function it's 72 bytes we're going to put in 80 bytes so we we already know this but we can just automate this anyway so let's first of all just update this with our binary name phone shop and this is going to find the context for us so it's going to create this elf object and it's going to set the context to be used in this whole script to the properties of this l file so it's going to get the architecture the bits the operating system and things like that so whenever we're building our payloads we don't need to worry about saying pack this as a 32-bit um variable as a 32-bit address or 64-bit address whatever we don't need to worry about that we don't need to worry about if we're using shell craft and we're grabbing a shell code from there we don't need to specify what architecture and what operating system it will do all that for us because we're specifying it here we can also set the log level so debug's really handy if we're trying to identify any problems with our exploits or set that to debugs uh to begin with and let's get this offset so there's at the moment it's stepped for 32-bit i'm going to comment that out and just because we're going to read from rather than the reading from the program counter we're going to read from this stack pointer because it's 64-bit and then we're going to find the offset so we just need to update this slightly as well whenever we run the process it asks us what we can go ahead and just double check this we run it says what do you want to do we want to buy so we're going to enter one and then it's going to ask us for details so let's say here let's copy this actually we're going to need to send a couple of statements so the first one it's going to sit say send line yeah it's send line after this anyway i'm going to send it one and then it's going to ask us to enter details so we'll say enter details and that's when we'll send the payload we'll wait for the program to crash and then we'll be able to read this from the core dump so let's go and comment some of this out for now and oh that was the wrong thing to run let's run python exploit and this runs through you can see there's quite a lot of stuff going on because the debugging but don't worry about that and it's founders the 72 bytes so it's located the rip offset 72 bytes so now we want to have a look at the the address that was being leaked and verify if our suspicions were correct let's go back once again to the right function so we have our cell function here and we want to go and see if if we enter too many characters into this read statement is it going to leak the next value on the stack being this local 20 being the this data location and if we get that can we then subtract the offset and get back to the pi base so let's go and try and put that together now so we start the program we're finding the offset we this time we want to sell something let me go and just copy this and after we get our initial output we want to say 2 and let's just run through this again so let me clear that we run it put into it says what do you wish to sell i'm going to copy this you don't need to copy all of it you could just do it after the question mark but i kind of like sometimes just to be able to see um centerline after just be able to see looking through the code what it's what's going on you know um not really necessary so it's asking what do you want to sell it probably doesn't really matter here this was where i think it was a 32 byte variable and it took in 31 so it doesn't matter we could say anything and then we're going to do this again send line after let's see what else it asks us it's probably easier to do it from gear just so that we don't we don't keep getting cut out here how much do you want for it and this is where we want to try and put in some different values so if we put in six if we remember before we didn't get any problems it was whenever we started to put in whenever we put in seven we started to see some funny looking characters so i'm gonna do i'm just just send it seven a's and then we're gonna want to receive our address let me let's try and run through this i'm just gonna do prints io.receive let's run through it python exploit and it comes back with the a's and this question mark okay i'm gonna say uh we'll change this i'm gonna or i'm gonna change this to i'm going to add another line here we'll say receive until and we want to receive until we get our a's back and that new line so i'm going to do a new line and then we're going to print out what we receive after that invalid in for literal uh we're missing out until receive until we run that and you see that then on our next line the first thing we get looks like our address so we can go and have a look at another example for this what i'll do is i'll do codium dot dot slash uh shooting star i remember we had some leaking on this what do we have star shooting star.py and i'm just going to go here and find the leak is right here so just going to grab all of this code and we'll do similar thing here so instead of printing that out we're going to say our leaked address is equal to [Music] oh unpack and we're going to take in this io dot receive and we'll say this is the leaked address and print this out so we'll try to run that now python exploit we get our leaked address which is good we want to go and verify that the address is correct as well so let's let's run this with gdb if i run this with gdb it prints out our leaked address it's closed the connection but did we we printed the pi base here somewhere right so printed pi base there we have our leaked address and the pi base if we have a look here we can do python c actually we should have got the uh what i'll do actually what i'll do to make that a little bit easier i'm going to go back i'm going to say pi base there and then i'm also going to say pi base and then let's get the address of our data section this is what we're expecting to leak so i'm going to take this i'm going to copy that and we'll say pi base 0x let me run that again close down gdb terminal clear this let's run it again and we'll see closes the connection but that's fine because we're just looking to have a look and see does this address match so we've got our pi address and you can see the second address does match so in the first address that was just up high base in our second address we've got our pi base plus the offset to the bss section which we know was this pointer here so this is important because what this means is although we didn't leak our pi base address we know that this address that was leaked is equal to this address plus the offset because we've just calculated that there so if we go back to our code and say the address that's leaked out here we can say our pi base put this in a new line pi base address is equal to our leaked address minus what we just added on right here so minus this value and now if we print that as well let us verify that this works as expected when i close that i'll just run this without the without gdb we run it we get our leaked address we get our oh i haven't updated it print out the pi base by base address run that again and this time we get our leaked address which is in here and now we've calculated our pi base i should have run that with gdb actually just to let you see that i'll run it with gdb just to see that it matches up with what we see in gdb so in gdb or pi base is this value and the leaked value they both match up to what we have here so we know that we've now calculated our pi base correctly which is great because it means from now on we can actually just jump to other locations of the program using the offsets that we find in geardrop or in object dump or ida pro or whatever you're using actually an even better idea than what we just did would be to update our elf address so our elf is loaded here normally if you load the elf and you set this up you can just access different functions and things like that in this case we didn't know what the base address would be so now that we have leaked the address well i mean we could find that out in this case but whenever we run it against the server we're not going to be able to so in that case we want to update our elf with the address that the server leaks back to us because once we know what the base stress is then then we can just access our elf as normal without having to worry about pi if that makes sense hopefully it does so i'm going to set the elf dot elf dot address is equal to our leaked address minus this and then that's actually our pi or pi base let me update that to pi base and now that we've got our pi base address we can essentially start looking for rop gadgets so we know based on some of the static and dynamic analysis we've done so far that we have a buffer overflow in the buy function but we only have eight bytes so we can only write one address so we need to find a rop gadget in the program which is going to give us some more stack space and allow us to pivot and once we've found that that um gadget once we've got that working we'll know how much uh additional space we have to work with and then we'll have an idea what kind of rock chain we can put together to actually get a shell or print a flag because we know that we can't execute our own code on the stack so even if we do a stack pivot and create a load more space we're not just going to be able to inject shell code we're still going to need to return to lib c and get the call the system function so it's like liking some of the other challenges we've done up to now we need to also leak a lib c address because we've leaked the pi base address but we haven't got access to lib c yet but one step at a time let's start by finding how we can create some more space on the stack and and uh triggering this buffer overflow so to find our gadget let's go and have a look in ropper you can use ropper you can use rob gadget you can search for rob gadgets inside of phone tools as well but sometimes it doesn't find or it never finds all the the gadgets so i recommend doing it in in wrapper you can do wrapper dash dash file uh pony shop and that will give all the gadgets you can also then use some different flags we can do dash dash search and say you want to search for example pop gadgets so we're probably going to need to actually let's do this now we're going to need to get the offset of the pop rdi gadget later because we're going to want to whenever we do finally go to return to libc and get the system function we're going to need to pop the bin sh string into the rdi register so that it can so we can call system on it so let's just throw this in now uh pop rdi is equal to zero x and this is the offset obviously we need to use the elf address as well so once we've leaked the pi address pop rdi is going to be equal to alpha address plus pop rdi but we don't need that yet just show in there as an example this is kind of what we're doing we're going through we're finding the useful gadgets and then we'll hard code them for now into the code later on towards the end if you stick around for the bonus content i'll show how we can search for this sort of stuff in prone tools and how we can automate a lot a lot of it so we don't even need to search for gadgets but it's better getting to know how to do it manually first i think anyway anyway first we want to do a stack pivot i'm going to do console here if you console we can do help and then get a list of different commands we've got available you'll see that one of them is stack pivot so i'm going to run stack pivot and it found one gadget now this isn't actually the gadget which we're looking for so let's let me exit out of there and we'll do search and i'm going to search for sub and instead this is the gadget that we're interested in so this is saying we're going to subtract 28 bytes from the stack pointer and then we're going to return so if we've only got one address that we can inject if we inject this address as our uh whenever into our stack pointer if we overwrite the return address it's going to execute this which is going to set the stack pointer back 28 bytes and if you remember whenever we did our buffer overflow we had let me go back uh entry let's go into the funk to buy function here you'll remember that we had 72 bytes and then we had the return address so if we write 72 bytes we could actually write our shell cut we could write some rop gadgets not shell code because we can't execute shell code we could write some wrap gadgets 20 up to 28 bytes up until the uh until we overwrite the return address that that probably didn't sound too good let me rephrase that we could write 72 bytes of padding minus 28 bytes because we're gonna do 72 minus 28 bytes of padding and then we're going to do 28 bytes which are going to be our up gadgets and maybe some more padding and then we will do the return address of the of this gadget so essentially whenever the buffer overflow occurs it's going to run this gadget it's going to jump back 28 bytes to the beginning of our gadgets and that's going to be when we're going to that's where we're going to put our our up gadgets to leak a libsy address so then we'll be able to go and look for our system function and things like that so it'll make a bit more sense when i start to put this together let me grab the offset of that and we'll go back to the code and we'll call this sub rsp28 so if you've watched some of the previous videos the hyperbox ponen challenges that i've put walkthroughs for i think the last one where we need to delete the lib c address we leaked the using the right function so essentially what we want to do is we want to call a function in this case we're going to try and call the puts function and we want to leak the address of the puts function in the got table so as long as puts has already been called that means essentially that the program's already already made a call out to lib c and has populated the address of that puts function in lib c now we know that as soon as we call the buy function or the other function the first thing it does is called puts so we know that table's going to be populated we don't need to worry about populating it first which is something that we i think we did have to worry about on a previous example um what we do need to do is find the address of puts so we could just look for the puts call here and use this address offset uh we're going to make life a little bit easier for ourselves and we already did do that actually by setting the elf dot address equal to this leaked address so we actually know that the pro tools knows the uh the address of all these different functions already so we can kind of go ahead and just start to put it together so before we build up a payload here we'll build up a rock chain so i'm going to create a new variable here this is going to be like a payload to go inside of our payload so we're going to call this rock chain we're going to do flat flat will mean that everything inside this is you can see here it's going to take an arbitrary number of arbitrary nested lists two poles dictionaries it will then find every string and number inside of those flatten them out etc so basically the context that we've defined up here it's gonna any addresses any numbers things we put in there it's gonna make sure it all works properly with in our case the 64-bit linux elf executable if we're dealing with little endian addresses it's gonna know that it's gonna do all that for us we don't need to worry about it because we've also done our elf address here we don't need to worry too much about calculating addresses here the first thing we do want to do is uh get our puts into the rdi so first we we got this remember we got this pop rdi right here so we've got the offset and we're going to say the first thing in our rock chain is going to be elf dot address which is our pi base which is calculated plus pop rdi the offset pop rdi and that is going to put the next value that we put that we have that we place here it's going to pop that into the rdi and that value is going to be elf dot got dot puts which is going to you can you can always go and print out the the got table and stuff here we could just do p pretty print uh p print uh elf dot got and have a look at things if you need to but um so that's what will pop into the rdi is elf dot dot dot puts and then we're calling elf dot plt dot puts just similar to how we've done in previous examples and this is essentially going to call our plt puts on and it's going to put out the got puts address which is going to be our foothold into the lib c library once we once we once we have that location then we can just remove the offset of the puts function in libsy and get back to our base and then we can then add the offset of our system and i'm sure if you watch the previous videos you'll have it you're kind of probably sick of hearing this by now but just for you know it's important to reiterate and for anybody who's maybe missed some of those videos might not be too aware here finally we're going to put in another address so where do we want to return to we're going to print out our our um libc puts address but then we don't want the program to just close we want to go back to the main menu so we can run through again and actually send off our payload so in here we'll say elf address plus and then i'm going to go to pawnshop i'm going to go back to in fact here is our function right here one three two a so let's just do here zero x one three two a so it's gonna run puts it's gonna put out our got puts address and then it's going to return to the main menu so we can then carry on as we were so that's cool we've got four addresses here so this is gonna add up to 32 bytes it's four eight by addresses 64-bit addresses it's gonna add up to 32 bytes we need to adjust our padding obviously so we've already calculated our offset it was 72 and we've calculated that right here but we can't just put 72 bytes and then our sub address because then our rock chain is not in there so here we're going to say padding is equal to and i'm gonna just put in i'm gonna do offset minus the length of the rock chain and that means if we go and modify this then that'll be taken into account here and then we can just go and build up a payload so payload is uh at this offset it's going to i'm going to put in a dictionary that offset sorry not a dictionary a list that offset we want to let me try and improve the format of that a little bit oops why is that deleting i'm just trying to move it down a line all right it's not all right i'll just do i'll just do this this is a lot more messing about than i was planning to do right there but it's done now there we go that looks good to me all right so we've got our offset and we're going to say at this offset we want you to insert our rock chain because the offset sorry not the offset the padding padding because our offset is 72 we want the padding which is the length of our offset minus the length of this rock chain and we're inserting a rock chain and then we're inserting our sub rsp so just like here we need to do elf dot address plus uh sub rsp28 so this is what's actually going to be executed it's going to execute this it's going to jump back 28 bytes to the beginning of our rock chain it's going to execute our rock chain which is going to put out the gots location the got's memory address and then it's going to jump back to the main menu so that we can go and continue again basically so i think that's good let's um just to try and make this a little clearer let's try and run through this in gdb and just see what's going on behind the scenes i've actually sent this payload as well so i'm just going to copy this from up here because we're doing the buy option now let's paste this in and change this to io i don't believe it's going to let me try and run that just quickly python exploit it's waiting so you see it's already returned to the menu there so instead of send line after i'm just gonna send line okay just type it up by hand send line sending one and then we're sending the payload let's try that and okay it came through it looks like we've not actually tried to print out the leaked address or anything but yeah let's go and debug this and see and see what's happening i'm going to go back to our code here we have the puts it we have this read which is where it's actually reading in our this is where the vulnerability is we have this read call so i'm going to just copy that we'll do break rva at that location so i'm going to do break rva at that offset i'm just going to once it knows what the pi base is it's going to insert a breakpoint right there so if we go and run this now with gdb we can see that we've stopped at the did we stop at a breakpoint yeah we stopped at a breakpoint here although it looks like things kind of carried on there let's see okay it didn't stop properly let me go and enable i o interactive here try that again okay so it stopped at the break point this time just swapped into interactive mode try and move this over here so we have a breakpoint let's see what's happening with the instructions so we have the call here i'm going to do next to go to the next instruction and you'll see that in our rsp now we have our cyclic pattern which is the padding that's been inserted in our instruction pointer now it's adding to the rsp 48 let's go and have a look at the code um so it reads you can see right here it adds 48 to the rsp okay and then the next thing that's going to happen though is it's going to sub from the rsp so we can actually go and have a look let's let's do x over 100 x i can just you can just do rsp dollar rsp we can actually go and have a look we can see all of our paddings there and we could go and have a look and see what these addresses are this basically is going to match up to our rock chains to our rock chain so we have this sub let's go next then next we have it's going to return okay we'll go to the next it's going to do this sub 28 so let's have a look again at our rsp here's our rsp right here and if we let's actually do rsp minus 28 you can actually check there minus 28 let's go next instructions it's actually done the it's done the sub and now we have this pop rdi in here because let's go and look at our rock chain again that's exactly what we're doing we're popping got puts into the rdi so the next address on here should be that got put puts address let's go and have a look at the next address on the stack we have yep got puts is the next address on the stack so that's about to be popped into the rdi if we go ahead and do next we can see here that the rdi um oh sorry didn't uh we didn't have the pop rdi that was the next instruction on the stack so pop rdi is about to occur so we'll do next and we'll see now that the rdi has the puts got plt in it and then if we have a look here the next thing that's been called here is puts plt to call and puts plt and because uh the puts in the got is in the rdi it's going to print that out again we can do next and we have then the and then we're returning the elf address is going to go back to i think i've gone into some of the puts instructions there but yeah that's going to go back to our main menu so hopefully that kind of showed a bit of what's going on behind the scenes so if you go back we have a look here and we'll see right enough it has printed out some address here it looks like a libsy address we have this 7f so um we need to capture that now so let's just go and copy the exact same thing that we have up here we are grabbing the leaked address so we send the payload we grab this leaked address and we're gonna set that to this is our got puts okay we're gonna print that and hopefully if we run this again i'll run this without gdb we run this again and it hasn't quite printed that out let me um strip this dot strip and run that again um okay let me try receive line and strip it and there we've printed out this address so it's got we know it's the got puts address but we could if we wanted to just to verify it we could run gdb again we could just hit continue wait until it finishes oh invalid address okay let's try that again okay it worked that time we got our guts address it printed that out got puts and then we can do x and give it that address and we'll see yep that's the puts address right there so if we wanted to calculate offsets of stuff here as well we could also do that we could p system to print that's the address to system and then we could calculate what's the you know the offsets from here but we'll go and do that in our phone tools scripts now so let's go back to our exploit code here we're leaking out the got puts we need to find out then we need to get the offset this we can find out the base so i'm going to say here uh we'll do libsy base is equal to got puts minus and then we need to find something here to we need to find the offset so we're gonna print this out let's see base and let's go find the offset now so we can do this we can do this in a lot of different ways but uh what i normally do i'll do ldd phone shop we can see the libraries that are linked to it we can see we've got our lib c here and we can do read elf dash s and this will give us basically all the sections it's giving us all the addresses we can just grab out whatever we want to find so i'm going to grab puts and we'll see here here's our puts at libsy we've got this one as well they're actually the same offset so don't worry about it so we'll copy this we'll go back here and we'll say this is what we're taking away and that's our lib c base address and then from there we want to find obviously our system address so we'll say give us the location of system and this is the offset of that so copy that um let me paste that there for a second just copy and paste all of this and system address is equal to our libsy base plus this offset that we just found and we can just repeat this for anything we need to need to find right so paste these in here we need to do the same for our bin sh address because before we call system we need to put the string the actual string bin sh into the rdi so that it'll be it'll call it's not just going to call system with nothing nothing in there again we can do this a couple of different ways i'm going to do strings dash a dash t x and then pass in i need to copy this again copy that we run the strings i'm gonna grep out bin slash sh slash bin slash sh and we find this is the offset of that string so we'll copy that and go back to the script we'll put that in so this should be all of our all of our addresses oh we need to do our plus so we're we're adding this we're not subtracting it we're just doing that to get the base address that should be good we could have done this other ways as well oh i just closed my terminal by a mistake we could have done this some other ways as well so let me go back to desktop ctf hike the box phone phone shop remove some of these cores and we could run this let me do python exploit gdb we stop at our break point here we're in our break point so we could do let me do search just get a help up here search so we can do search dash t string and then search for bin slash sh and we could find it this way as well so that will actually find us the address and then we could calculate the offset from there we could do the same again for our system and things like that so we did p system before and we could say pi base can we say pi based system no okay um but yeah we could go through and search for things to calculate things in there as well again if you stick around at the end of the video we'll actually use pawn tools to search for some of the rock gadgets and strings and things like that and also just load in lib c as a binary directly and so we can just we don't need to worry about offsets at all we can just use the function names and then we can just swap out the version of libsy depending on whatever the server is using so we'll move on to that later but let me close that i'm going to run this without the without gdb and you'll see here we've got our puts our libsy our system address and we've changed that one to um system bin sh was the last one was not bin sh and that will give us our various addresses actually i will run that just one more time gdb and i'm just gonna do continue it's giving us all of our addresses there so we could go through and say all right this is a system address let's make sure it's got it right so we can do x and then the address we'll see yep it's got libsy system that's what we were looking for we could do the same here say x and we'll see all right that's not printed out as we'd like so we'll do x over s and then we'll see yeah that's been sh we've printed it as a string instead just to verify that we've got everything in the right place and we've got our we've calculated our all our all of our offsets correctly which we have indeed done so we can now move on to building our main payload where we're actually going to try to spawn a shell so i'm going to copy our rock chain from earlier because we don't actually need to make too many changes to this it's going to be quite a similar format our new rock chain is going to we're still going to need to pop into the rdi but this time instead of popping inputs we're going to be popping in our bin sh string we're going to pop that into the rdi and then we're going to call system so we have our system address and then we have uh so it doesn't really matter too much after this i'm going to put i'm just going to leave this as the elf address this would return to the main menu but because we're calling system we're not actually going to get to this we could also just put in some padding you know just it doesn't doesn't really matter because we're not oops we're not too worried about what's going to happen after the shell after the shell closes if you were worried about it you might want to just you know if you want to keep the server running after the shell closes you might want to have this go back to some you know the the main method or whatever it shouldn't really matter for us i'm just going to do it so that we don't need to worry about changing our padding at all so we can just go ahead and grab this up here we don't need to calculate our padding again but i'm just going to put it in just in case there are any size differences and our payload is exactly the same we're just rebuilding our payload it's just a new rock chain that we're passing into it and then we want to send this off to this to the well to the binary in this in this case into the server after that so here we go this is our final payload let's clear this let's run python exploit we run that we get through and we see here at the end it looks like we've got a shell we don't have any ender file if we can go through we could go through and actually see exactly what's being sent backwards and forwards you can see that this is so it's no shell code because it's a rop gadgets but if you have a look at these values it'll actually be the same values as we have here so for example what was the last address or um let's see we have our system oh we've got an ender file while reading that okay we have our system for example which is or i've been sh i can see our bin sh there so we have a five six so five six zero one zero one seven f seven f seven d obviously in reverse order and if you go through that it's gonna be everything that we saw on the stack so it looks like it just closed my shell there yeah it did so let me just try and run that again and while we're here we'll do ls we'll do uid id and see that um we do have a shell if there was a flag here we'd obviously be able to cut it out so now it's the case of testing this out against the server um if you watch the previous example where we did the return to libsy you'll know that we're gonna have to go and try and find out what version of libc is running on the server because it's unlikely that they have the same version running as we do and if they don't it means all these offsets are going to be calculated differently so because we haven't loaded in libsy here we can't just go and load in different versions of libsy and test it out we actually have to go and manually update these values for each different version of libc that it could possibly be so we'll show how to do that now so i've just added comments throughout this code nothing's changed functionally it's just uh been commented and maybe formatted a little bit better and i'll put this up on github but let's go and spawn the hack the box server and test this remotely first of all so just take a copy of that server address and i do python exploit dot py and because let me just i mentioned this earlier but because we have this template anytime we want to run run this remotely all we've got to do is just pass in remote as the argument and then the server and the port just kind of like how we did with the gdb at the beginning and there are other things you can pass in here as well notice that this is passing in debug no no aslr um so let's run that let's do remote let's paste that in we just need to take this colon out and we run that we get our end of file so notice that it didn't actually give us a shell we're not able to list the directories or check the id or anything like that so this is exactly what we expected because we don't know what version of libsy is running on the server it's very unlikely to be the same version as ours if it was then that should have worked although there can be some slight differences in um sending and receiving data on the compared to the local binary to the when you compare the local binary to the server some send lines might be different might be some missing new lines or additional new lines in places and we'll i think we'll see that here as well but let's go and see how we can find out what version of libc is on the server if we take one of these addresses this is the address that has been found on the server let's go to this libc database here you can query so let's start over uh oh not start over let's remove these we're gonna add a new query and in here we're gonna put the address you don't actually need the full address it's only the last three or four digits which are important but we're going to say that this is the puts call we could have passed in a different one oh well we couldn't have passed a different one whichever one we're leaking out we need to find out so we'll say this is puts and that's the address of it and then it'll come back and say there are three possible lib c libraries that that could be and then it's the case of us going through and manually testing each one of these so if you click on the first one the amd 64 which is a safe bet for us in this case in um i can't remember which which lab or which challenge we last had to do this on in behind the box but i think there was quite a few more matches that we had to run through but you find which which if you find them you go through each one starting with maybe whichever's most likely to be the case and then essentially we'll go through and put these different offsets in there so if we go back to our code we have our offsets here and you can see that in our version of libsy we have to subtract this value to get back to the base but in this version that we're looking at we have to subtract this value instead similarly if we want to call system this is going to be the offset we can have a look at the difference there as well so if we were comparing this to r lib c um you could just take the difference but let's paste this in here and finally we've got the bin sh so you can list all symbols but obviously it's selected the most important ones for us place this in as well and if we save that and go back let's try and run the re run it remotely again you see we've got end of file again but it's as i mentioned previously it's not it's not just the lib c library which can change it can also there can also be some issues with the formatting so whenever we last ran this let me actually let me just go back very quickly i'm going to change those addresses back to our correct addresses and i'm just going to run that python exploit locally we get our shell again um we can list the files here but notice this difference here whenever we sent 51 bytes here so we leak our pi base and then whenever we're trying to leak our got puts we send 51 bytes we get back 0x a9 and it comes back with this menu and the reason it does that is because we had this up to return to buy after it's oh well both of them are set to do that but in this case we're looking at the leaking um here so we can see that is what happened locally it returned 0x a9 bytes if we go to the server version we'll find in this case it's sent off 51 bytes so they sent off 51 bytes just exactly the same and if you look through these it's pretty much the same just with the correct you know addresses but instead of 0x 9 a nine bytes it's receiving zero x five eight by it's back so it's actually not getting the full menu back um and this is where you just kind of have to play around with the uh play around with the send lines and receive lines and things like that so in this case i believe rather than send line after we want to change this to just send after let me test that out and see if that works on the server we run that okay we've still got end of file let's see we still didn't get that full menu back and so it doesn't give us that option one let's try and comment that out and if we list the directory here now we'll see that we've got our flag.txt on the server i'm not going to print it out because i'm conscious that i have been doing that in some videos and i should probably just um just to make sure people don't just skip to get the flag and at least i mean all you really have to do is run the script so it's not too much work so there we go we've seen how we can do that locally and against the server so let's do a bit of bonus content and have a look at importing the lib c library and see how that can make a life a bit easier and we'll also have a look at using rop objects as well so let's load in lib c first of all we load in our elf up here i'm gonna load it in after we start the program we'll do lip c equals elf just like we're doing up up here and then we'll go and get we'll go and get our default location first of all so do ldd pawn shop and let's put in the address of the libsy library where we have where we had our original offsets and paste that in that and where we get we get our libsy address here so instead of lip lipsy bass we'll say the lip c dot address just like we did with our elf dot address we'll say lip c.dress is equal to the got puts that we leaked minus the offset which we know about this offset is the offset of the remote version though our local version was different but we don't need to go and calculate it again instead what we can do is we can say the lips address is equal to lib c dot symbols minus uh sorry um is equal to the got puts that we just got minus libseed.symbols.puts and that should get us back to our base address and then if we want our system address we should be able to just say well actually we shouldn't even need to calculate it here we could just use it from now on but let's try and say here lib libsy dot symbols dot system and finally we have our bin sh which we were which would calculate the offset for instead what we could do is we could say here this is equal to next and we're going to search for lips we're going to do lipsc.search and we're going to search for the bin slash sh let me just make sure we've got the null terminator and this should identify everything this should get everything as before let's let's test this out and actually let's test this out locally first of all so i'm gonna return this back to sendline and i will have this as well send line after let's test this out and see if it works so we run python exploit and we get libsy bass is not defined where do i still have lipsy bass lipsy bass lipsy bass okay right here so we're still printing out lipsy bass instead i'm gonna print that lip c address let's try that and it looks like we've got a shell yeah there we go so this worked all as it did before it's calculated the system it's calculated live c calculated got puts but instead it's used our actual libsy library here so what's cool about that is that we can now go and if we were testing this against a server we could download all three of these libraries and we could just test it by by looping through and just all we'd have to change in the code is we would have to update this string and you could just create a loop to loop through you could download every library so there could be like 10 20 libraries here so you can download every library and then you can just loop through every library until eventually you get a shell i would be an easy way to do it let me download did i download that already let me download this actually i will w get it to our current location so we save that right here and that way we can just import this i'm going to copy that paste it right there and let's grab the server address here again so we'll grab the server address we'll run this with remote and pass in the ip import we can end a file error but remember that we need to modify our code slightly not because of this but just because of the the issues we had down here so we want to comment this out and we also wanted to do a was it just send line or send after here we want to do send after right there let me save that test it again and there we go we're in so what was cool there is our offsets didn't have to change right so if we coded this for our lib c library and we used all of these um symbols to calculate our offsets all we would have to do is just keep swapping around these libsy libras to see which one actually worked against the server rather than going to manually pasting those and rather than having different versions of your script for each different system that you might want to test it on you can do that all in one so with that done let's also see if we can make this script look a little bit better using some rop objects so let's start by let's start by creating the wrap object anyway so we'll do rop equals rob elf and that's going to be our context binary you can see here what's the help say it's a class which simplifies the generation of rock chains and it gives you some examples here there's plenty more documentation on the pwm tools uh site anyway uh so we create a rope object if we wanted to have a look and see some information we could do p prints rob dots gadgets let's try and run that and you can see here it's printed out the gadgets note that it won't have all the gadgets so look how many gadgets there are there if i go now and do rocker dash dash file pawn shop you're gonna get a lot more gadgets so something worth bearing in mind from as far as i can tell from the documentation it seems to just say that um there is no way to display all the gadgets through rough uh through phone tools and if you want to find them you'll have to do it outside of the script so anyway with the wrap objects created what we can also do there is we can search for gadgets now so rather than us manually specifying these pop rdi gadgets we can say oh it's not let me select it we can say rop dot find gadget uh actually note the some of the options we have here available as well so you have rock.call and rob.cor will actually try to make a call to a rockchain so if it can find a resolvable function you can call the function so if system exists somewhere for example you could call system and pass in the arguments required here and it will build all that together for you and it's really a good way to learn actually because you can do that and then you can go and do rob dump to print out the structure of that rock chain and then you'll know in future you can kind of analyze it and see oh that's what it's doing behind the scenes and you'll know how to build them up in future so it's helped me out a few times whenever i've struggled with things manually i've automated them using the rop objects and then i've kind of analyzed what's happening behind the scenes to know how i can achieve the same thing manually so we don't need to call anything yet anyway let's do rob dot find gadget and we want to pop rdi here so we'll say pop rdi and then return so in in this case it's pop rdi and then a semicolon then return so we're just separating each of those inside of a list and then i'll bring back it'll find all the gadgets so we want to take the first element the first gadget that you find that's pop rdi return we want to take that basically and then we should be able to do the same thing here as well for the sub so we just paste that in we'll just change this to sub rsp 0x 28 and then we're going to need to add that red as well hopefully that'll find that as well and when we get down to our first payload here as well we have our first payload we're creating that rock chain we can say here rock.raw and then passed in a list of parameters so we can essentially just pass in this list of parameters right here um let me take some of the comments out just for a second just to make it easy to copy and paste so exactly the same thing there we've just done wrapped up raw instead and then we just basically say that this is that's the that's our rock chain so i can do let's do rock let's do chain here we could do this at any point but i'll just turn that into a chain now and that's essentially what we'll send off as a payload so we'll take this out we're still calculating our pad in but at our padding instead of sending this actually let's also send let's just send this as well the sub rsp send that all as one and then yeah at this pad instead of sending a list of items list of uh rop gadgets we can and addresses we can just say here we just put in here rob because we've already converted it to a chain in fact let me take that out there i'll take that out there and put that in there chain and we don't even really have to do that we could just take this out of the payload altogether and paste it in there why not put that all as a nice one liner and then we can go ahead and we can do similar throughout and let's do something similar here we can actually probably do something even better here let's i'm going to reset the rope object now that we've calculated the lib c address i'm going to reset the rop object and say rob is equal to rob this time of libsy you could just create another object but we shouldn't need our first one again from now on so there we go we create that of the of libsy and then we can do rop dot system because it's just going to look up system in libsy and it's going to find it no problem and that way it'll take care of the putting bin sh into the rdi and stuff for as well we can just say call rob dot system and then pass in the in fact let's grab that we don't need to calculate this bin sh at all so just paste that in there we'll take out this whole bin sh we'll take out the system we don't need to calculate system um we can print out the libsy address because we do need to set that anyway but that should be good so we still need to build up our our rock chain here i've actually just realized there's going to be an issue with our padding because our padding here we're calculating the offset let me so we we'd i'm gonna take this out of here yeah okay i'm gonna take this out we might be able to put it in there put the pad in actually yeah i'm gonna leave it in there i'll leave it in there let's try and do i'll do rock chain here and let me just see we'll see how this works out i don't think it's gonna work too well but we'll give it a go we might need to just account for this as well but here we go that's adjusted the padding and there's the rop i'm missing the dictionary okay everything's looking funny so i know i'm missing another bracket there we go and that's looking better okay so there's that and then we've done we've got our rop system we're probably going to need to let's see if we can just add on to that rop dot raw and then i'm going to add on this alpha dress to go back i don't think we need to go back anyway but i'm just going to add that on anyway rob raw put that inside a list even though there's only one element and that's our rock chain so in this case we'll do minus the length of rop dot chain and then we're going to send that off as rob dot chain as well actually i'll turn that into a chain here okay so we have a rob and then right here we're going to send off our up but we still want to send off our sub as well actually i'm just going to put the sub in here as well because i'm not too sure if it's going to work and it's not really a big deal to just add in we can we can have in here rob and then just having the elf address plus the sub so hopefully this is gonna work i need to take this out of here i'm not 100 convinced but it might do so let's try it all right so we'll run this again see what kind of errors we get okay um non-type object is non-subscriptable so it didn't actually find our sub rsp gadget okay let's see let's print out the gadgets again see if it actually shows up in there if it doesn't show up in the gadgets no it's not gonna find them so we'll do pretty print rob dot gadgets run that again and do we have any subs in here no i don't actually see sub so it looks like for whatever reason the subs aren't identified there so all right we'll just go back for the sub we'll just say in that case we have to manually specify the gadget so i'll just put in what the old offset was there's our officer and then whenever we're doing our sub we'll need to say oh we were already doing elf dot address so that would have caused some problems anyway oh would it no no that would have been okay all right let's uh let's run this again and we have that the non-type object has no attribute chain let's go back to the code so here's where we're getting the chain um i'll take that out there and let's just say here then we'll do rough.chain we need to do it here as well i just want to just double check run that again okay this time we get bin sh is not defined on line 105 so i've obviously got that in somewhere still bin sh and oh what are we doing here we're still okay so we don't want this at all we wanted to do just wrap dot chain so take that out i don't know why i still have that there i should really not do this on the fly i should i should record this but i should do this before i record the video because it's taken [Music] longer than i expected all right uh rob chain here as well and fingers crossed and boom we are there we're roots on the server we've done this all with rob objects and using the lib c library that we imported so i hope you've enjoyed this video if you've made it to the end congratulations you've got the patience of a saint and i'll put these scripts up on github along with all the others try to comment them throughout and uh yeah i hope you've enjoyed the video any questions comments leave them down below thanks
Info
Channel: CryptoCat
Views: 925
Rating: undefined out of 5
Keywords: hack the box, hackthebox, htb, hacking, wargames, challenges, capture the flag, ctf, reversing, reverse engineering, assembly, reveng, crypto, stego, pwn, exploit, infosec, security, kali, parrot, ida, ghidra, pwntools, malware, tutorial, learn, hacker, cyberchef, buffer overflow, bof, debugging, gdb, gef, peda, pwndbg, rop, ropper, binary exploitation, pen-testing, disassembly, python, ret2win, radare, r2, objdump, readelf, ret2libc, stack pivot, pivot, rop objects, return oriented programming, stack space, pwnshop, ropgadget
Id: RNqJjO3uf98
Channel Id: undefined
Length: 87min 20sec (5240 seconds)
Published: Sun Mar 28 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.