CSAW'19 - PWN - Ret2libc w/ PWNTOOLS (baby_boi)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's going on everybody my name is John Hammond and in this video I want to showcase this baby boy challenge from seesaw CTF 2019 this was the first challenge in the pwned category or binary exploitation and it's I guess trivial right and that it's a low 50 point challenge in the binder exploitation category but this is not really my strong suit and I learned something really cool in this challenge that I wasn't aware of before so I wanted to share it with you so let's go ahead and get started it gives us a couple files to download here it says welcome to pone as the description and we're given a netcat command that we could use to connect to the service so it has to work remotely right I'm gonna go ahead and create a little connect on a sage script just so we can save that and connect to it as we needed to so I just created a simple bash script and copied it in there so we'd be able to actually run that command and don't have to worry about oh here is my actual netcat host and port number etc it's just a convenience thing that I like to do it says hello Here I am and gives me some hex value here so hello okay and that's it that's all the binary seems to do but we can go find out what it really does because they give us the binary of Lib C like the C library shared object file and the baby-boy C source code so let's download all these I'm just gonna right click and hit W get or copy location so we can throw that to W get will download it and let's work through all of these so if W get that do the exact same thing cool so now we have these files here we have the Lib C we have the source code and I had downloaded it previously my bad okay now we're clean let's see what this is this is a 64-bit executable so we know we're working a 64-bit architecture x86 64 and not stripped binaries so if you wanted to you could do things like Riel f-- on all of that and see what we have in here nothing particularly interesting but we don't need to do all that because we have the source code so let's take a look at baby boy dot see and this is our source code looks like we're just including regular standard libraries for see we have a simple main function with arguments that just flushes the buffer here or works with standard out centered in centered error that works just fine for us and we have the buffer variable with 32 bytes and it's just saying hello Here I am with the value printf so we actually get to see one location of a c standard library function and know where it actually is in that binaries runtime that's gonna be pretty handy for us because it looks like the next line is a gets function call so gets is just that hey it's super dangerous function never actually use this if we check out the man page forgets it says this will read in a string from standard input but it's deprecated it doesn't check for any buffer overflows it doesn't verify whether or not it actually is within the bounds of the buffer that you pass to it that variable that's created there so it tells us up here hey never use gets it's impossible to tell the data in advance before how many actually characters were reading in so we could very well be subject to a buffer overflow attack and that's exactly what we're gonna do so we know that that is the shape of the binary that's what we're working with I'm gonna clear out all of these things in my sublime text so that's kind of clean for us and now let's go ahead and start to beat up this binary I'm using pone tools so I've got pone cyclic that I can actually use and will actually be able to use that to fuzz data or actually send a cyclic pattern to it we know that it is about 32 just pulling up the source code here we know that it is 32 characters for a buffer so we could send more than that let's send like 50 just to send it to our baby boy here and I need to mark that as executable so don't forget that chmod plus x baby boy and now if you wanted a pony cyclic let's just send some data to it what I'm using pone cyclic what that's doing is just actually creating a cyclic string so we'd be able to tell okay if we're looking at D message where our instruction pointer crashes or overflows we could see that we know we're getting that segmentation fault so we can see that just easily let's check out D message see where I'm at and I'm getting a general protection seeing a trap there that doesn't really help me so I know okay let's tone that down let's go to about like forty-five and throw that at our baby boy binary check out D message one more time that's probably pretty hard to see sorry my face might be in the way but okay now we see we're overriding 6c 6-1 6-1 606 B is that actually what we are overriding though let's I'm gonna I'm just gonna tweak this lower and lower we'll get to 40 I'll check D message now I get a segfault at zero okay so psyche fault at zero means that I probably just clobbered the instruction pointer 64 bit so we're RIPD rather than AIP and maybe there's just a null byte in there let's flood that again with 41 and see if we get potentially our last character maybe an A in there may be something lowercase a so let's check our D message output and still zero we're not fully clobbering it we're just trying to massage this input so we can find our offset is or where we can clobber that instruction pointer because we know that's gonna be overflowed and there's our six one and six be in there okay so that's two so we can assume that 40 is gonna end up being our offset and we can start to build out an exploit or payload to actually work with this we don't have any functions that we could jump to like a simple like get flag or print flags or get shell so we need to be able to probably track down the system function call within Lib C and then go ahead and actually call that function and we'll just get a shell will run Ben SH and it will work for us so let's check it out let's go ahead and create a script I'll call mine API get a shebang line rolling for us and I'm gonna be using pone tools so from bone import everything and let's grab our binary here let's create an elf object for baby boy and I'm actually gonna want to differentiate between I'm running this locally and running this remotely because we have our connect script and that is the hostname and port number here so let's say port can equal that host can equal that and let's set like a variable just a boolean test for us local equals true or not whether or not we're actually going to run this locally or remotely so say if local then my P will equal ELF dot process probably that sounds weird to say sorry my I'm to create a process from this binary and I'm just gonna call that variable P because that's shorthand really easy really simple if we were remote or if we were not actually using a true value of local will use these host and port values and let's set P to a remote session of host import so now we're gonna we know we're gonna connect to it and let's go ahead and print sorry let's print out P dot receive so we can see we're working with here and I'm gonna use this in Python to before it dies and goes away 2020 is coming quick note if we were to use Python 3 we return the same information I'm using the Python 3 pone tools that you can find on github I think the project isn't maintained anymore but it's still usable we use it for katana and other projects so be notes ok we're receiving this information as bytes and it's actually a little problematic in the way you might normally use poem tools especially if you're working with a binary and trying to work with some Lib C libraries etc etc it gives us some nice check SEC output so we can see we don't have to work with P ie we don't have to worry about a stack canary or anything but we know we're working on a 64-bit executable and we cannot execute off the stack so we can't use shell code we have to use something like Rob or the return oriented programming language stuff to really abuse this binary ok it's giving us the system location I said system and that was the wrong word it's giving us the location of the printf function in C in our Lib C library and we can see that ok that is going to change every single time because of a SLR maybe on the remote system or even on my locals let's run this is Python - sorry but since we can know that value even at run time because the program will tell us then we could potentially determine where the base address of Lib C is we could just go ahead and work with it we could just actually subtract out we know the location of printf so now we could find the base address of Lib C and because we're given the Lib C file we know we're system is so simple ret to Lib C attack because they simply just give us printf let's go ahead and work with that I'm going to load just a l DD I'm gonna use l DD to find out where my local computer is actually using my Lib C rendition looks like it's in /lib x86 blah blah blah so let's say Lib C can equal elf of that and if we were remotely we would use the Lib see from that Lib C that's in our current directory right or lid C 2.27 so whatever so let's just slap that in there okay so now that we have Lib see let's carve out where we're receiving that print F location and let's go ahead and use that to find our lip C base address what I'm gonna do is I'm gonna say P dot receive until and let's get until the Here I am kind of syntax there Here I am with a space and let's do P receive just following that and I'll say that that is stripped so we don't get that newline character there let's print that and now let's run our script still working locally now we can see hey we've got our print F address here just displayed as that variable let's go ahead and actually make that a number because right now that's a string so I'm gonna use the int function to wrap around that and I'm just gonna say that's base 16 that should be inside of my int function sorry so we don't need to print that anymore but left let's actually call that printf now if I were to print printf Python treats it as an integer just in decimal if you wanted to see that in hex now we just encapsulate that variable and it's a number that we can work with so perfect now that we know where Lib C is now that we know they're print F is in Lib C at runtime we can find out the base address of Lib C so let's check that out let's say Lib C which is this object we created in poem tools we can actually use Lib C dot address and say this is where the base address of Lib C is going to be you have to set this when you're working with that Lib C object from poem tools by default it's zero so all the offsets between symbols and things in the G ot or the PLT are just based off of zero within the file as it knows but you can set it to something else corresponding the Lib C file you're working with and then all of the other obstet s-- SKU excuse me all the other offsets or the symbols you want to pull will just be the correct value so let's see that we can say Lib C address can equal printf because we just got that value minus where we see the Lib C symbols address of print F indexing just like that okay so with that syntax just a little math to some quick subtraction there we can find out the base address and the offset there I'm gonna print that out I'm gonna print out Lib C dot address and I'll put that in hex so we can see it and let me just add a few display things here so we know what we're talking about when I show this on the screen cool printf we know is that all of this in Lib C base address now that we've done that math we know is that all of this and that looks like it's paginated well that's in the right kind of area in memory we can that make sense to us because this starts off the same way so now we've got base of Lib C and that means now that we've kind of corrected our live C rendition we know we're system is as well let me show you something just real quick if I were to run that same script doing same thing with Python 3 using the Python 3 poem tools this is the issue that I was gonna run into and I wanted to inform you about it is that when you try and retrieve that printf out of the symbols here it'll tell you hey Kier I don't know what you're really talking about because you have to index that with bytes and that's a stupid idiosyncrasy that you might trip on and run into I don't want you to have to end up falling on that now if I had that b prefix to say that's and bytes sure it'll be able to find it and run without an error so let's still use Python 2 when I run it and that works just fine for us ok so now we have our Lib C address our printf address and now we can say the real system is at lib see symbols of system perfect so now we could call system if we were to overwrite our instruction pointer that our IP value but we're not using regular 32-bit calling conventions now we're in 64-bit so if we actually want to pass an argument to system which we do right we want to actually run it with a value loaded into RDI so those are the 64-bit calling conventions it looks for arguments in RDI and I think RSI and other locations then it gets into our one stuff I can't remember off the top of my head but RDI is the first argument that we're gonna need so we need to find a gadget or some location in the binary or within Lib C that we could actually return and work with that pop RDI instruction so we can suddenly fill a value inside of our argument and give that to our system function here so let's do that I'm gonna actually use Rob gadget and when you use Rob gadget you need to use tactic binary you can see seashell is trying to autocomplete for me stuff that I've already done here so let's just give it the baby boy binary because maybe we could find stuff in there that we need rather than looking in Lib C and we have a lot of results here it's kind of hard to see on the screen sorry but one of these real quick for us is this pop RDI and Bret so pop right here in return everything will have a return the end of it because we are using Rob return-oriented programming so that way we can just jump to this position move back to where we were and that's how Roth works it's pretty cool let's go ahead and take that address and let's just say pop arty I can equal that and let's start to build a build out sorry excuse me a potential rob chain let's say we want to pop RDI but what do we want to pop into our di what value do we need to give in there well we need to give it that bin SH string but we're gonna find that we can find it within the binary what what you can do is actually use Lib C because that's given to us we can use search and we're just looking for a string here so we can just pass in bin Sh when you do this you'll note that that's actually to give you an iterator or a generator object so if you want to get the first result I just run dot next and now we have that address if we were to check that out in hex cool now we have a location within the Lib C where bin SH just that string exists and we could give that to system because we've popped it into that RDI register and we'll use that as an argument and 64-bit calling conventions so let's say that that value is our bin SH string or a variable that we want to use here now we've got a Rob chain we can use prop chain pop RDI bin SH and let's go ahead and call system with that I like to use this syntax I found it or at least kind of like that idea Caleb my roommate uses it a lot especially if he's illicit tiger in the discord server and you've probably seen him in other videos this is a really cool technique that he uses and he's much better at buying or exploitation that I am if you create a rock chain just like that inside of a list you kind of read it in a more assembly like fashion and then we can just join it together by using P 64 or P 32 on all of those and that way it's in that little endian format that we need to be able to pass to our binary so I'll just say our four are in Rob chain so now we have a wrap chain that we could use and we need our payload which will just say a random junk random stuff 40 times because that'll fill up until we get to our return instruction pointer I'm sorry are all right P all right our 64-bit instruction pointer now that we've hit that offset now that we are flooding into the instruction pointer it will pop in our rob chain that will call pop RDI with vin sh and then jump to system so let's try that let's go ahead and use P dot send our payload I think the Sun line is what we want let's find out and now that we've sent that we should have theoretically jumped to a shell or call a shell so let's move that into interactive so we can see it work here we go and switching the interactive mode I'll hit enter a few times then I'll run ID and now you can see that's John so I can run Who am I I'm still John and we have a shell I can run commands so we just called Ben SH and now we have control over that system I'm running this locally though so all we have to do now because we've setup hey here's our host and port here's the remote service that we're connecting to and using the remote Lib C we can just switch that to false up top here and we can go ahead and run our script and we should be able to work with it but we got an end-of-file while reading interactive mode I don't have a shell so this is what I struggled with for a little bit of time Caleb and I were wrestling with it it sounded like people even on the discord server and those that were playing seesaw CTF were wrestling with this I did not know this this was a whole new thing that I got to learn and props and shout out and thank you too crypto was his name and discord who reached out to me and checked in with me and said like hey I got this you need a hand what's up cuz my at my exploit I said like I don't I don't know what's going on my exploit works locally it does not work remotely what do I do there's no way to research that thing I couldn't I couldn't track it down so the guy said to me the remote service is on Ubuntu 1804 and I'm running on 1604 locally and apparently Ubuntu 1804 in its 64-bit sense I don't know if it's strictly a bun - 1804 maybe maybe other 64-bit distributions or things do this but apparently it works memory the stack hold this whole binary realm works in a sixteen byte boundary so that means that our payload and things need to be aligned or within a kind of sixteen byte multiple so what we have here for our rob chained pop RDI we know that's eight bytes and same with venice h and all that gave us sixteen total here but system that's not so right now our stack pointer is not being fully aligned to that sixteen byte boundary and we're not able to call system on the remote machine so what we could do is just fill that with a little bit of garbage or some padding just some junk with eight bytes somewhere really just not in our pop RDI alignment there because we need that to fill that argument and not after a system because we need that filled out before over the calling system our stack pointer needs to be set and aligned within that boundary before we end up calling the function so we could put it just before system or put it at the front here let's do it just before system and we need just padding and junk a good way to do that is just check our ops one more time or our gadgets here we have one of these that is just a simple ret command there so let me take that and let's just create a variable for that let's say ret can equal that value there and we have everything else that we need to build out our Rob chain and let's say ret right before we call system okay so we have some information some testing to setup whether or not we're running this locally or remotely maybe it would be a cool idea to do this with our course so we don't have to just be modifying our script while we're working with it we determined the address of Lib C so we could get the proper system location we got a couple gadgets between pop RTI and ret and we found where bin SH is in our Lib C and now we built out a Rob chain it was P 64 put it in the little endian format that we needed use the correct offset and we're sending it and we're going interactive so now let's see if I run this working remotely local is false will we get a shell it doesn't kick me out whack enter a few times looks like we're still in ID we're baby boy all right LS we got it now we have a shell on that remote service on that remote system and we did it cat flag there it is flag baby boy do to do to do all right let me clear that up so it's more at the top of the screen for us and that is that so you go ahead and submit that a 50 point challenge still some hefty stuff I by no means am good at binary exploitation this was a learning experience for me I need to practice a lot more with this Rob Emporium maybe portable XYZ other resources and wargames that I need to work through so that I can get better and we can get better you can get better too when it's that's the community that's the family but right now I need to focus on OS CP sorry thank you guys for watching I hope you enjoyed this if you did please do like comment subscribe I would love to see you guys in the discord server there is a link in the description if you are willing to support the channel which I am always so grateful for and so thankful for I have a patreon account also link in the description would love to see you on there super duper grateful and super thankful for all that you do to support so thank you guys i'll see in the next video
Info
Channel: John Hammond
Views: 17,499
Rating: undefined out of 5
Keywords: buffer overflow, ret2libc, nyu, cybersecurity awareness week, cybersecurity, cyber, computer science, capture the flag, ctf, pwn, binary exploitation, libc, gcc, c++, c programming, assembly, x86, 64-bit, elf executable, reverse engineering, john hammond, hammond, baby_boi, tutorial, learn hacking, learn binary exploitation, diy, how to
Id: E8Ykh-UC2f0
Channel Id: undefined
Length: 24min 3sec (1443 seconds)
Published: Sun Sep 15 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.