 They told me that I couldn't have a wireless mic up here because apparently they're afraid I'm going to hack it. I don't understand. You know that you're at a very interesting conference. When you walk around and Bluetooth pops up. See, I've got a Bluetooth tool that just pops up everything that it runs into. It's almost like a denial of service sometimes. You know that you're at an interesting conference when you get names like White Witch or... Oh, here's a good one. Nut cheese. And yet I'm still amazed at the sheer numbers of people who forget to turn off their Bluetooth. Ad Defcon. But that's not why you came to hear me today. But I'm giving people a little bit of time to walk in. Hello, my name is Atlas. I like what I do and I do a lot of it. A while back I'm in a subway in DC with a friend of mine. And I forgot to ask his permission so I can't say who it was. But this friend is very well known by most of you. I guarantee it. And he is the cream of the crop in security and in the hacker arena. Well, anyway, this guy is talking to me and he says, Atlas, explain to me how buffer overflows work because I'm just a little fuzzy. I've read a little bit about it, but I just don't have it. And I told him an answer. But I thought to myself, if this guy needs a refresher course on heat buffer overflows, I think I should probably... I thought they were going to provide me music. I said, hey, there's probably a lot of other people out there that don't quite remember how they work or just never knew. And that's cool too. They're actually kind of esoteric. Clicker? No! Great. I kind of love that. Wow, this could be very interesting. There we go. It works again. So this is remedial heat buffer overflows. Basically that means I understand most of you guys are lead enough to have done this before or at least roast the subject before. So this is for you. This is a talk about how to exploit buffer overflow of vulnerability, specifically with a heap and a DL malloc heap structure in place. We don't have a lot of time. Sorry about that. In the man page for the get s function, there is an exceptional note. It says, never use get s because it is impossible to tell without knowing the data in advance how many characters get s will read. Basically, don't use get s because we're in C now. In C, you have to tell it much like assembly. This is how much room I want to give you. And get s just says, starting point. Let's just race. Looking for a zero. And you hope that it's still within your buffer. But if it's not, who cares? You get a little crash. Not a big deal. F get s also has some issues. It is a step up from get s. There's a ton of C functions that give you all sorts of beautiful, scary functionality. But the big ones are string copy, mem copy, the s scan f, or the scan f series or family of functions. One that a lot of people overlook is actually not a function in C at all. It's an assembly thing. In fact, it is the glue that makes all these functions work. And it is the move s assembly op code. Anybody heard that? Yep, a lot of you. So move s takes a parameter or a prefix, says repeat. Hey, repeat this many times. Just move from here to here. That's pretty cool. How many of you are programmers or have written C programs or Python programs or any other language? Thank you. Excellent. Big, a large amount of you. You guys get to watch me walk up in front of the table because of the whole wireless thing. So if I fall off, please try to leave my badge alone and my wallet. You can take... Okay, no, I'm not going to give you permission either. When you're programming, what do you use to store information? You use a variable, right? There are two types of variables in a C program. There are local variables, and those get stored on the stack. There are also dynamically allocated variables. In other words, I don't know at the time of writing how much data I'm going to need. So we set aside a huge chunk of virtual memory space and allow for a heap. Now a heap is a very low level function, but it is not operating systems specific. We'll get into that in just a second. A heap is dynamically allocated storage at whatever size you need, and it is... It can be very fun to secure. Who's heard of a stack-based buffer overflow before? In fact, who's heard of a buffer overflow at all? Show of hands? Excellent. How many of you know what it means? Thank you. Excellent. Good. These buffer overflows are beautiful. You start at one location, and you meander. You meander. That might need to be right there, so you replace it very nicely for the program so it doesn't crash. Keep going, and you overwrite something of very big value. Oftentimes this is the return pointer for your function. Heap, however, doesn't have the return pointer of the function stored in the heap. So what can I do? Can I take over a computer system using a heap buffer overflow? Well, before we get to that, I'd like to back up and say overflowing a buffer is valuable. Let me hear it, everybody. Overflowing a buffer is valuable. Why is that? Wow. Yes. Can I summarize? Because I don't remember everything you said. It was really good. But basically there are several reasons that buffer overflows are great. You can stop an entire machine, or at least a process, from running denial of service. There are several other ways that you can exploit, not meaning shell code necessarily, but exploit a computer program because of a buffer overflow. First of all, you can overwrite other variables on the heap. Now, for instance, if your program has in it, members of this group stored in this heap variable have administrative access to my tool. And you happen to buffer overflow just before that. Well, you can go, oh, yeah. Hey, that's my group, Atlas Group. Suddenly you have administrative access. You can control things you should have no business controlling. Another interesting one that's often overlooked is the ability to take a string variable, for instance, get rid of that nasty little null at the end that keeps the printf from printing more beyond that point. And instead of overwriting, you can now, with the help of a printf that very likely already exists for you, get access to read whatever comes after your buffer. So we'll call that end of string overwrites. You're overwriting the null at the end of your string. But of course, the crème de la crème, the most exciting, this is going to kill me. Hold on a second. The most exciting thing that we talk about when talking about heap buffer overflows is tinkering with in-band information. In-band management information, to be exact. It's a deliq process, and it's one that's not very well understood. So a little bit more about heap memory in particular, generically speaking. A heap is a chunk of information that is given to a process by the kernel. If the process needs more, it goes back and has a very brute force request to the kernel. Hey, I need more space. Can I have more space, please? And the kernel will say, yeah, here's a couple gig. Okay, maybe a couple mag or whatever. It's up to the program to then decide how to manage that information. How many of you have a bedroom at home? How many of you have a clean bedroom at home? Get out of here. I don't want you in my room. Why is that? Well, because many of us understand whether we're good at it or not. We understand that open space requires management. So DL Malik is an implementation of a heap management system. It was written by a guy named Doug Lee, that's the DL part. Somebody asked me about that earlier. I forget what he said, but it was really funny. Yeah, sorry, sharing my internal jokes. So Doug Lee wrote this heap management system, and he made one mistake, or maybe it was intentional. I'm not beyond guessing that. And in my line of work, I like to think along those lines. I think the people who wrote the stack, I think they were just really evil. Because who else would say, hey, start here and keep writing over the return pointer? Doug Lee and several other heap implementations, they make use of what's called in-band management data. In other words, my chunk is 101 bytes long. Do some math, make it round off so that it's stack aligned and all that beautiful stuff are aligned in some way. At the very beginning, just before what you see when you get a heap variable, the four bytes leading up to your memory space are actually a counter that says, hey, anybody looking at me, the next heap is X number of bytes ahead of me. Okay, so heap buffer overflow. Wait a minute. I want to change that one. We'll get there. In this presentation, I use the words chunk and buffer fairly interchangeably. Understand that when you're talking to somebody who hacks around in a kernel space all the time, which I don't, I spend some time there. I enjoy it, but they will say no. What the kernel gives you is a chunk. You're talking about a buffer. But I will use them both. So please don't get lost in that. It worked. So for example, we make a call to malloc. This is the call basically that says, I need this many bytes. And this can be a variable. That's what's so cool about heap. So we're going to say, I want something at least 1024 in size because that's what I'm going to use of it. I don't really care if it's 1048 as long as it doesn't eat up too much memory space. So malloc goes out, says, based on these rules, I'm going to cut a chunk and give you a pointer, four bytes into the chunk because we have our management stuff there. One thing that's important to note is that malloc and its counterpart free are called so frequently that most sanity checking that you'll probably think during this presentation, why don't they just check? Most sanity checking costs too much. If you take something that's iterated thousands of times during the boot of an operating system, for example, and you add a second here, even a half a second over time, Vista doesn't boot very fast. Then again over time Vista doesn't boot very fast anyway. So I guess that doesn't matter, does it? But in the Linux world, we see that not much has been done to correct this. Some stuff has. The important part when dealing with this type of heat buffer overflow exploitation is the function called free. If we fill up a buffer and overwrite the next buffer's management information, the thing that's going to make use of that, however, is a call to free. So you've got two buffers. The second buffer has management information just past your buffer. You overwrite that, you call free and free reads that information and makes decisions based on what you've written there. That slide seems out of place, doesn't it? But I'm going to say it anyway, because back in 2004 Microsoft vulnerability was found in Microsoft core library in the parsing of JPEG files. Do you guys remember the GDI buffer overflow? Do you guys remember that it took third party person to release a tool to even help you figure out if you're vulnerable? Because everything uses this thing. Anyway, he's a good friend of mine, Tom Liston. I had to give him a shout out. So he wrote this tool. He works for Intel Guardians. Good bunch of guys, good friends of mine. The problem with learning heat buffer overflows and the reason that it's not nearly as focused on as stack based buffer overflows is that stack based buffer overflows are fairly consistent between platforms, at least among the same hardware. So you've got BSD, you've got Linux, you've got Windows and Windows and Windows and every other version of Windows. There are several implementations of a Malik system. Doug Lee, I enjoy his very much. RTL is what they call it in Windows. The BSD-PHK implementation, I hate this one. There is no in-band management and I'm having to hack a binary doing this right now. In fact, you guys have been down to CTF, right? After this, I will be running down there because my team is still in a heated struggle for first place and you guys should all come down and check it out. It's really cool. This is what good guys do to go be evil. There are also several other implementations. System 5 has their version. BSD and AIX have some, did I say BDS? That means something completely different. What's most important isn't what happens when we allocate a buffer with the Doug Lee Malik. What's really important is what happens that we never see. You see, after you free a buffer, Doug Lee says they don't need that information anymore. So you know what? I'm going to use some of it. Before, we said this guy right here just before the buffer is going to say how many bytes to the next buffer. When we free it, we're going to use several more chunks of memory to store more information. Because when you write a program, you're using a heap. Your heap chunk, you maintain that. You manage it. You have pointers to it that last throughout your program. But when you return it back, you just say, I don't need that anymore. Doug Lee then has to take care of it. So the Doug Lee Malik sticks these buffers that are unused into a doubly linked list. Anybody know what a doubly linked list is? They were kind of a pain to do back in college, but they come in very handy. So Doug Lee stuck all these suckers back into a doubly linked list. And the particular exploit that we're going to talk about today has to do with this doubly linked list. Specifically, what do you do when you have two buffers that are freed in this doubly linked list? I don't know. Well, you just leave them alone, right? They point to each other. You're cool? Uh-uh. Because on your hard drive, what happens when you've got chunks of data spread all over your hard drive? It gets slower than Vista. Did I say that? Yes. It slows down because the operating system is having to tell the hard drive, go here, go here, go here, go here, go here, go here, go here, go here. Malik or heap implementations also have to deal with the same thing, fragmentation. So when you get two free heaps next to each other, the dog-on suckers, they got to be big. So we join them using a tool called Unlink. And Unlink is where the magic lies. So in our example, we have a buffer. Now I could have chosen 100 bytes or 104 bytes and it probably would have been prettier. I chose 101 because it proves a little bit more of how this works. And I don't know about you guys, but when I had to learn this, it wasn't about reading about it. It wasn't about the theory of how it worked because I understood that. But it was about the bits and the bytes and how it actually worked that got me to write the presentation. So if that's cool with you, I want to get into the details. 101 bytes. Malik, deal Malik, then allocates truly 112 bytes. There's a little mathematics to go into there. I wrote a question for my friend G-Mark for Hacker Jeopardy that basically took this to heart, but then I pulled it out later at the request of a friend of mine who says, dude, they're not going to know that. They haven't seen your talk yet. So I pulled it. Anyway, the idea is you call Malik, you say I need 101 bytes. You don't know that Malik needs to know that you need four more or that you don't tell Malik that you need four more than you really need. Malik adds that on. So you've got 105 bytes and then in the interest of alignment and beauty and bliss and even numbers, deal Malik then extends that to the next 8-byte boundary. What's an 8-byte boundary? Well, that's a thing in assembly that... No, no. An 8-byte boundary is, well, 8, 16. It's a multiple of 8. Nothing magic. I had to throw this slide in because a buddy of mine heard that I was giving the talk. He said, dude, you're not going to include Windows? I'm not coming. So here's for you, Lenox. If you came, I know I saw some of your friends, but I didn't see you. Anyway, Windows actually, and I won't spend much time here, Windows has a very similar idea of allocated buffers. You own them. You take care of them. You tend to them. When they are checked in, however, they are checked into an array of doubly linked lists. It's the biggest difference. There's some other details of how they work and I won't get into them. I don't want to confuse you, but I had to throw it in. So we have heap buffer that we've allocated. We've stuck in my first name. Then we have another one that includes my alias, Atlas. And then I say, huh, I don't really want to give out my first name. So I delete the first buffer and it becomes a freed buffer chunk. Melox says, I understand that you don't need this. I'm going to take care of it. I'm going to use the first eight bytes. How many bits is that? Yell it out. 64. 64 bits. I'm going to use the first 64 bits of your memory space. So you've got your memory pointer to the very first byte of what you see. The first four bytes, but the first byte you see. And from there, it sucks up eight bytes to 32-bit addresses. The buffer in the linked list, it's been deallocated just before it. And the buffer that's been deallocated just after it. Got that? There are a couple other places within your buffer that it will write to. We won't get to that now. I have slides that actually explain that better. So when the memory is allocated, so notice this is used, this is kind of what the memory space looks like. We have a long integer, 32 bits. Then we have 101 charrs, characters. And then we have some padding at the end. Right? Right? And then we have a buffer. This is a bit closer to what you will see when looking at a freed buffer. I tried to find a good way to do this. I chose to do it in a struct type format. I do have something that I stole from Once Upon a Free. You guys heard a frack, right? I'll show that later too. I wanted to take two different approaches. But for those of you who like the struct, here it is for you. So we start out with our long. This is the length of your buffer, including all the rigmarole at the end, the padding and that. It is an even number unless the previous guy is not in use. We will say that many times. Don't worry about it. Just keep it in your head. If it's an even number, the guy before me is not in use. If it's an odd number, the guy before me is in use. So you will look through here. You will see the number 71 or 71 hex. Forgive me. But that doesn't mean that 71 hex later is where the next buffer starts. It really starts at 70 hex later. But that just means that the guy before him is in use. Then we see two longs, the previous guy, the next guy. Then the remainder of your character space. The length, again, of your buffer. I don't know why they did that. I have a feeling it was for performance sake when freeing the guy before you. But anyway, there is another copy of your length without the one. So it's always even. And then the pad size. Everybody's still with me. If you're not, raise your hand. See, that's how I get people to tell me that they're with me because nobody wants to stick up their hand. So as I mentioned, the magic happens in an area called unlink. It's actually a macro. Do you guys understand? Who here understands the difference between a macro and a function? And don't worry if you don't. Okay. In C programming, they allow you to do all sorts of things that help you as a developer think about the program, aside from secure coding. You write a function that you want to call over and over and it becomes something in memory, its own entity in memory that can be called from all sorts of different places. Oh yeah, from up here too. And at the end, there's a return, and hey, that return pointer that we talked about, then sends the instruction pointer back to where it came from. Most of the time, actually, there's some fuzzy stuff there that evil people like Invisigoths from Concerto do that actually don't return where it's supposed to. Anyway, then you have macros. The idea behind a macro is I want this to be exceedingly fast so it's going to be inserted in line wherever I write this. But because I know that I will dork that up. If I do it 25 times, like I'm going to have to. So I write a macro, I put the macro in, the compiler says, oh, it's a macro, and I just want to make sure that that gets replaced before compiling. Also macros are used, yes, I know macros are used for numbers that you don't want to have to call to a variable all the time. It's a performance thing. It's cool. So unlink is a macro, and the basic idea behind unlink is the guy behind me has a forward pointer, and the guy in front of me has a backward pointer. Well, I'm bowing out of this puppy, so the guy in front of me, his back pointer, should really point to this guy over here. And this guy over here, the guy behind me, the forward pointer should point to the guy over here. I didn't say why. Can anyone guess? Why would you use unlink? The use of unlink is actually, it has several uses in the DL Malik. The use that we will be speaking of specifically is the use of joining two adjacent buffers into one larger chunk that can be used for many more things. So you call free. Your buffer is now freed and has all the nifty little management stuff involved. But then unlink or it checks to see, hey, is this previous buffer in use? And it looks at what? It looks at that first four bytes. What's that? Exactly. It looks at that first four bytes just before your buffer. Is it even or odd? So it's even. What would we do? Would we call unlink or not? Yes. I heard the answer. Yes. You call it. Why? Because the one isn't there. It's even. It means zero, which means false. The guy before me is not in use. However, notice that this buffer, the deciding factor of whether or not I call unlink is up to me because I just overflowed the guy before him. Does that make sense? But the devil is in the details. Do pay close attention. Ooh, that really didn't show up very well on the projector. Maybe with a laser pointer, I can highlight it. How's that sound? So an in-use memory buffer, I told you that we'd go over this again. I stole this from Once Upon a Free. Give them credit because they did all this ASCII art. I modified it a little bit so it's adapted. So we've got the chunk. Starts here, previous size, 32 bits long. Of course, if it's even or odd, mean something. I'm sorry. This is before our chunk. I didn't adapt it very well, actually. I should have moved this down. This is a little confusing. I apologize. Here's where our data starts. The first four bytes is the size and that's or, bitwise or, of previous in-use. Then we have our memory. Then we have a next chunk. And again, that should be down lower. This last 32-bit integer, what does it really say? What's it mean? Previous size. Well, that's this up here. I'm sorry. This size right here minus the previous in-use. So we're good. Yuck. An unused memory buffer. Somebody who's been sent for deletion, so to speak, if you're in Detron has also, just before our buffer, we have a previous size. Then we have the size of our buffer. Then our forward link, 32-bit integer, a pointer. We'll see this in real data in a little bit. And a back pointer. Then we see the old memory. And again, we see the previous size. So we've been lost. We got a map. We kind of got an idea where we're going, right? Okay, don't show your hands. Just agree. Good. So when unlink is called, back and forward, as I'll call them. Obviously, it's bick and fid, but they are used to determine what bytes to overwrite in memory. Because in the end, that's what this is all about. It's not about, ooh, let's make this point to some other part of the link list. No, no, no, no. We want to overwrite bytes. Is that not why we're here? Yeah. Why is that? Well, because if I overwrite the right bytes, I can tell the instruction pointer where to go. And yes, that has the same meaning as when I tell you where to go. It goes to hell on a handbasket. Or as a hacker thinks, it goes into my code where it should be. So this happens whether you're collapsing backwards. So you're freeing this buffer and collapsing backwards. Or you're freeing and collapsing forwards. Unlink is called both times. Both ways are exploitable in some operating systems or some implementations. So now we've got two hands. We've got a map. Let's take some real examples here. 804.964. What type of operating system am I talking about? Somebody yell it out. What's very common with an 804? Ed, you know. No? Yeah, sure. You're just being hard. It's Linux. POSIX, Unix. You name it. They probably have an 804 or something in there. 804.964. This is actually Linux. And 804.AOE8. Oh, wait, no. Those don't look right, right? Why don't they look right? Because that's not typically where a heap lives. In fact, in our test program that we will get to in a minute, 804.AOE8 is the address of a got entry. Somebody yell out what got means? Global offset table. Global offset table. Thank you very much. Global offset table. How is it used? For exploits. Yes. Yes, I like this guy. By design, the got table is a place where relocated parts of code that you didn't have to write because they're in a shared library are placed when you start a program. So how many of you have written a program that calls a library? A lot of you. Why? Because it's just so doggone easy. Why do it again? So the loader for an operating system, and in this case Linux, says I need the SSL library. I'm going to load it up here. And because we're a PLT got type thing, we're going to stick the beginning address for this function in the global offset table. Meanwhile, I call some SSL command. Well, let's just say printf. People know printf. So I call printf, and I'm not really calling printf. Not right away. What I'm really doing, my code makes call to the PLT. Who can yell it out? Yeah. Procedure linkage table. Thank you very much. We make a call into this special area at the beginning of our program called the procedure linkage table. It then jumps to wherever your SSL library or your printf function really live. It's really easy. The loader has to just keep track of a small area. And it's called relocation. Beautiful thing. Helps us reuse code. Also a beautiful thing because if we can overwrite four bytes, we have a great place to start. At the bottom, you see an example heap buffer overflow for DL malloc. We start off with hexadecimal representation of an address and memory. Wait a minute. That looks kind of weird, doesn't it? But trust me, this is how it looks like. We are on a least significant bit first operating system. Who came up with that? I don't know. But the idea is, instead of 80496C4, we're going to start out with the C4 first because it's just cooler for some reason. C49604 and not just eight, of course. It's 08. Then we have another address placed here. What do you think these are going to end up being when we hit the free unlink mechanism? Pointers. Forward and backwards pointers, specifically. So we provide forward and backward pointers. D times 92, and I chose D for specific reasons, but basically it could be anything. Then I chose also to use a negative four. The reason is unlink doesn't care. What it cares about is that it is even and it has a couple other checklisty things that negative four is just beautiful for. So I use it twice. I use it here, and then I need a four-byte pad for this particular exploit. So I use pad zero. Hey, it works. And then I put another negative four because just before the next buffer comes what? It's length. And again, unlink doesn't care what it is. So I'm going to use negative four again. Negative four means what? Is negative four odd or even? Okay, not bitwise. Negative four is even. If you drop the negative, it's an even number. You see, you can tell it's an even number because of the C. Can you figure that out? Just kidding. So yes, it's an even number, meaning that my buffer doesn't, it's not allocated. I'll tell you why in a little bit. And then I stick the same two numbers afterwards. What do you think I'm doing? Why am I bothering to do this upfront stuff right here? Well, because I'm trying to make it so that if they free the second buffer, I win. If they free my buffer, I still win. So we have a map. We have two hands. We have a flashlight. So we've just set up memory space to make my buffer, which is in use, look like it's unused, at least for most intents and purposes. And we mentioned the got. And got is so beautiful, and it is read-write. So we like it. There are a few gotchas. Unlink doesn't just do the overwriting that we want it to do. Unlink does two things. It does one direction pointing to a new place, but it also has the real problem of going the other direction as well. So when we unlink where you've placed your shellcode, the eighth byte through the 12th byte are going to get clobbered. Yes, for you, Litas, it's 7 through 11. It's going to get clobbered. Can't help it. Sorry. This is kind of how it works. So we start out with a couple opcodes in our shellcode. If you're shellcoding, you're probably doing opcodes in any way. Except, of course, if you're using that HDMoreGuys tool, who I love. He's really awesome. Metasploit. Because metasploit is just so easy. So we do our MSF payload and dump that to whatever storage facility, a file or whatever. And we then have to precede the payload from metasploit with some of our own bytes. We stick in an EB, which is a jump to a single byte offset. Which is important, because we don't want to throw any zeros into this number. One byte. So we jump 0x... 0xE is the length. Including the opcode, it actually ends up being 0x10. Or 1-0, sorry. We'll see this. I'm trying to explain it now, because in a minute, you're going to see exactly this. We then... Oh, I see it right there. EB0EAAAAAAA We use A's just because they're easy. They also provide decent knobcodes if you have any left over. Notice I'm not just sticking in eight A's here, because eight's really what's going to get clobbered. I wanted to show you a little bit more representatively of what it's going... of the structures involved here. So I used A's. Or three sets of A's. We can do this shorter, but there we are. Now here's where the gotcha comes. And yes, I realize if you want to get up and walk out, that's okay. I'll forgive you. They fixed this in G-Lib C2.5. In fact, I think I've seen it in 2.35. By a very... Somebody very intelligent adjusted the macro so that it says, just before we do this, hey guy to my left, are you pointing at me? Okay, good. Got him all right? Good, we're set. Now we can unlink. I was hoping that by the time we got here, I would have a solution to this problem. Buddy of mine, Chris Eagle, maybe you've heard of him. Rumor has it, Chris has a way around it. We're going to talk after the con. After he's no longer my enemy, and we're friends again, we're going to chat. So I wrote a little vulnerable program. Actually, it's a toy, not just for this presentation. So instead of just the very bare minimum of what we need, I started out and made a five heat buffer program. And I freed them in kind of a funky way. So take a look. Can you guys see this? I'm sorry, this font doesn't show up very well on the projectors here. I'm not hearing any complaining, so I'm going to go on. So hack me.c The typical includes stuff, nothing real special, standard lib, standard IO strings. Then we have a main function. Very simple program, actually. A main function, we set aside five, array of five character pointers to, I'm sorry, yeah, character pointers. Yeah, I know. Yeah, I know. You guys are thinking, wait a minute, a buffer or an array kind of makes it so I don't have to use pointers, right? And pointers mean I don't have to use an array. But actually, we are storing the pointers themselves. So that's why there are five. We also have a loop counter. And we loop zero to five. So zero, one, two, three, four. Okay, no, not five. And we create some heat buffers using the call to calyc, or C-alloc. You've got M-alloc. You've got C-alloc. You've got several others that they all do different things. C-alloc is intended to provide multiple buffers in a row with one call. And it zeroes them out for those of you who really care. Then we do a get-ass into each buffer, starting at four and going down to zero, just to throw in an extra kink. Let us play around a little bit. And then we have two loops here that print out the contents and free our buffers. Notice I'm stepping by two, so I'm doing the even ones first and the odd ones second. Y'all with me still? I wanted to create a tool that could provide more than just a demonstration for this class. For this talk. But you can take home with you, you can play with it and have fun and learn on your own, and not have to rewrite your own program. I hate writing test programs. They're really annoying. It's like, I just want to do it. So can you give me something? Who read the Ericsson book, Hacking the Art of Exploitation? Excellent book. I love it. In fact, I like it better, and don't get me wrong. I like it better than Shell Coaters Handbook. And don't throw eggs. Shell Coaters is great. Ericsson just really understood how to say, these guys need some examples, they need some hands-on, and they needed a very explicit teaching of what's going on. And he did an exceptional job. The guys who did Shell Coaters are awesome. Some of them are my friends. I'm not picking on them. They write more depth. But Ericsson did awesome with those examples. And I keep turning that off. So hack me details. We compile this down on a Linux system using GCC. This tells you exactly what I did. We get a warning. The get us function is dangerous and should not be used. Well, then it should be pulled from the library, you idiot. So I get a warning. Why would a developer ignore a warning? Then I use obsdump, which is a very cool binary manipulation, a binary analysis tool for elf binaries specifically, but they do Windows too. obsdump, using the R command, gives me the global offset table. I take a look here. It looks like the free function. Its location is stored in 804.964. Notice I didn't say it's going to be loaded at 804.964. Its pointer will be stored there. This is on your CD for Defcon. So don't worry if you can't see all this. I'm going to tell you what you need to see. A clean heap memory allocation of our program, mind you, not just some ethereal thing. Here is the 32-bit integer that marks the beginning of our first buffer. And if you can read it, it says 00000071. You hop down a little bit, and if you can see it, it also says, oh, right here, 00000071. That's our second buffer. How many bytes between this and that? I'll take hex. If you don't want to do the conversion in your head, I know some of you are probably just turning that function off while you're here. Yes, 70 hex. Pop down here a little bit, see the same thing. And a couple more. I only had so much room. So 71 means 70 hex or that with previous in use of one. 70 actually converts. If you pop up K calc, if you're using KDE like I do, it converts to 112. Wow. Everybody over here, look over here. This projector is better. I like it. I can read it. So I wrote this little exploit. Simple piece. It's in what language? Yeah, it's my latest love. Python. Import the OS module, import struct. I put in some shell code. 10 byte shell code. Anybody, is that not slick? Really, it's a lot longer. I chopped it. I create a variable called at. It says, this is where I want to overwrite. Two, this is what I want to change it to. I want to point here. And that's where my shell code ends up. I then create at. Which just converts this from a Python, a Python number into an actual byte. And I do the same thing to two. Then I open my program, shove in a whole bunch of crap, and I get a listener on the other end. The most important part here though is, you'll see I'm writing to one buffer here and another buffer there. That's just fluff. But then I write to the important one. I've selected one to be my buffer overflow. So I start out with an address that doesn't... No, wait a minute here. This is the shell code. Forgive me. We start out with the jump over the crap that gets nailed. We then do our shell code, and we terminate it with a carriage return. We write the next buffer, and then I just selected the last one to be our buffer overflow. So we start out with... This is an example that you should have on your CD. It only focuses on collapsing. Collapsing in one direction. I've written several. They're all there. Okay, thanks. So we start out with our buffer. We do our number 4, negative 4, negative 4, and then we stick our addresses. Flush it, and we're good. This is what the stack looks like before we free. I'm sorry, the heap. So we filled up one section of heap with hex 4, 5, which is an E. We have our number negative 4. We have our pad 0. This converts pad 0 in ASCII. Negative 4. Our number minus 12. That's because you go one direction. You're going to be offset by 12 bytes because it's not just the start of the next heap that you're talking about. It's an offset from the heap. The pointer to shell code comes next, and right here we're about to clobber that spot, and our shell code starts there. Notice, got entry, 804, 834E. So this is where the... I forget what I grabbed here. Free. This is where free lives in virtual memory space. After free, we still have pointer to shell code. Still have some negative 4s, other stuff. You'll notice this used to be pad 0. It's now an address. The start of our shell code, which jumps over that crud, a couple of knob codes, and our shell code. Next call to free is going to be sent to 804AOE8. And if you look up here, 804AOE0, 8 is halfway through. It's going to point to right there. So I was going to demo it. I'm thankful that I had the slides that show what the demo is going to be, basically. Here's my Python, interactive Python, the hacking tool champions, and Netcat to port 4444. Thank you, HD. I type the ID, or I type ID, and hey, the program ID runs on the other box. Demo. Not going to get to it. Sorry, I got two minutes. I was going to demo. It still makes me stupid. Here's the bad news. I talked about it already. Somebody very intelligent said, hey, these guys aren't pointing at me. Bomb. Corrupted, double-linked list. So what do we have left? Well, we've already talked about them a bit. Variable modification. End of string termination overwrite. Or be creative. First of all, heat management is a complex thing. There are many aspects to it. We've only started to scratch the surface. There's more out there. Creativity is how we first discovered how to leverage buffer overflows. It's about getting something and then leveraging it. Pen testers. What do you do when you nail a box? You say, woo-hoo, call the client. No, you pivot. You then leverage what you have. A couple resources that don't show up at all. They are on the CD. You should click them from there or print them off. Special thanks to my creator, my family, to Intel Guardians, who are dear friends of mine. Kinshoto for giving me an opportunity to get a start. My last place. Some of my closest friends and my team. Some graffiti. Because graffiti is cool. Bodgering Wraith, Menace, Jewel. Thank you very much, guys. Some of this stuff was stolen. You need to give credit, otherwise it gets sued. Some people actually do know who I am. Thank you very much. You've been a great crowd. I enjoyed it.