← All talks

PG - Introduction to Reversing and Pwning - David Weinman

BSides Las Vegas24:11661 viewsPublished 2017-08Watch on YouTube ↗
About this talk
PG - Introduction to Reversing and Pwning - David Weinman Proving Ground BSidesLV 2017 - Tuscany Hotel - July 25, 2017
Show transcript [en]

have you got everybody my name is David I'm here to speak about reverse engineering and pony I'm a security researcher at cynic I love listening to metal playing capture the flag snowboarding skateboarding your average millennial I love the Pacific Northwest that's my home I live in San Francisco I graduated from the Evergreen State College there where my interest in ponying was sparked I used to play with the CTF team called the canoe adducts and I'm still learning but seriously if you guys have any sort of feedback or questions like like my host said please feel free to share with me and you know we can improve the end result of this talk together in general the motivation

for reversing and ponying is cash there's a lot of money to be made when something is difficult it can feel rewarding to overcome obstacles and defeat challenges so for a lot of people it's just the pure challenge of it that makes all of this worth it I lift some I listed a lot of the more beginner oriented bug bounties and associated average payouts and I work at sin acts in that friends a great bug Bonnie where people like yourselves can make money and use skills related to the ones that you'll learn in this talk in our mobile application county assembly may be a review for some of you but will briefly introduce it to ensure that all of us

are on the same page my hope is that practical examples will keep interest fresh throughout the talk for everyone no matter what your skill level is so let's get let's have a round of questions you guys can respond with thumbs up or thumbs down who's seen a debugger before sweet who's written a line of assembly also alright nice so we're going to talk about bugs and techniques for studying programs in on disk and in memory and hopefully I'll have time to show you guys Poe and challenge at the end so let's start off with a demo

okay got it's this program it's got to strux there's they just represent various kinds of bears so we've got a polar bear and a grizzly bear notice that the polar bear has this field that's a it's a function pointer we've got a secret admin shell and edit polar bear function to printing functions for each kind of bear and here's our menu this is a simple menu driven program you can make a grizzly or a polar bear delete your bear print your bear you can edit polar bears and you can exit and then we've got our main loop here which accepts whichever option you want and then acts on it the bear creation option allows you to rename

your bear if you already have one that exists and allows you to create bears it uses malloc over here to allocate space for the bear and then prints the address of it and then it just accepts the various fields and you've got the same thing for grizzly and we've got our deletion options here which just free the memory for each for either bear and you can print your bear notice that the print option for the polar bear uses the function pointer that we saw earlier and then you can edit an exit so I've got a few questions for you guys again you can respond with thumbs up or thumbs down so if a function isn't called in the main

program like we saw that the that this the secret admin shell function is never referenced in the program does it get compiled into the binary or not thumbs up for yes tums up down for now alright cool it looks like we have people here have seen this kind of thing before are they grizzly and polar bears trucks allocated next to each other in memory okay and can the grizzly if you delete a grizzly bear after making one can you print it afterwards it's really credibly written isn't it so we'll answer these questions formally through throughout the talk so let's take a look at low level programming fundamentals for the 32-bit x86 CPU so a CPU is composed of a collection of

registers you can imagine a collection of registers as a reusable theater sign notice that over here we've got the list of movies and over here we've got this running message that just talks about small business in the same way our register illustration points out that these registers over here our general-purpose registers and then down here we've got pointers the other thing of note is that you can reference subsections of your CPU by different aliases so like a X registers the lower or talked or references the lower 16 bits and then so on and so forth for the other labels so assembly is about as low level as programming can get technically you can program in machine code but that

wouldn't really be any fun for anyone in assembly languages are sets of instructions that can take up that take operands which register which can be registers or constant values instructions are simple logical arithmetic or state modifying operations notice below we have this move instruction which is which just moves the constant 5 into the a X register and let's take a closer look at illustration of the compiled square function so it's color coordinated which is really nice this declaration relates to the function Prolog which just saves the stack frame for the collar and then allocates area creates a new stack frame for the body of this square function then we've we've got the the meat of the function which

just multiplies its argument by self so this instruction takes the argument and puts it into e^x and then this instruction takes EAX and multiplies it by the argument again and stores the result into EAX and then we restored the caller stack frame and returned control of the CPU to the caller so we've seen in general how code is represented at a low level but what does a process look like at runtime in memory I'm sure most of you have heard others talk about the heap and the stack these are two regions that most variable data is stored in heap is for variable sized data and the stack is primarily for local variables and function arguments whose size is known at compile

time the the this memory layout illustration is extremely simplified there are segments of memory that aren't shown here for brevity row data is known as read-only data it's used for immutable values thus read-only the data segment is used for initialized global variables so the stack frame holds the function metadata and local variables when a function is called the color has to pass along arguments to and a pointer to the instruction following the function call so that control can be returned back to the caller the Cawley has to save the color stack frame and then allocate space on the stack for local variables notice that arguments get pushed on right to left so argument two gets

pushed on first and then argument one gets pushed on then the caller can save its return address and the colleague can save the stack frame for the caller and then local variables are pushed on top down so var one gets pushed on first and then var two gets pushed on so now that we have the basics down for looking at assembly let's try our hand at a simple cracking

so on the left here I I'm interacting with this reverse me binary and then on the right and I've got a disassembler open this is called radar II and all it will look a little unfamiliar at first and all introduce pieces of it and you'll start to become a little more familiar as I move along so let's just try entering some garbage data into this binary and we see that obviously that failed but what we can do with this is we can take this failure string and see in the binary where it's referenced in the code and start to figure out how it's working internally and see what is the correct data so I'll just pay it

I'll just search through the strings in the binary for fail is this beautiful for everyone probably not huh you guys want me to make it bigger

is that a little better cool all right so we see that the failure the failure straining has this has an address right here this is the address of the failure string so we can take that address and we can cross-reference it with the code and we see that it's used in the main function and in this Sim dot is a winner function so first let's take a look at where it's used in main so we'll seek this to main and then we'll print out the disassembly and it's a little much but we can scroll up to the top and see what's going on so we start to see things of interest look this is f gets

which is receiving our input and print F over here unfortunately it's going off the end of the screen but you can see here it says enter an input so that's our first input prompt and as we learned that arguments are pushed on right-to-left unfortunately it's going off this screen but radar gives us this really nice function prototype for F gets and it shows us the prototype so on the rightmost we have the file pointer for the stream that we're getting input from and then we've got the size of the input and then s which is the destination the destination buffer so this EAX at the top pushed on it s this is the file pointer and then hex a

that's the size and then local 20 hex that's that's where our first input is so we can take that out remember that as we reverse continue to reverse here's our second input which is stored in local 16 hex and then we've got this call to stir it along which just takes local 20 hex and converts it to an integer we can tell that it's an integer or decimal rather because hex a is 10 and so that's the base that start along as using anyway the output is taken and compared against this hex 5:39 return value for every function can be expected to be in the eix register for those of you that can't see this is that

the EAX register it's compared with hex 539 which is in decimal is 1 337 so that's our first correct input we know that then sim dot is a winner is called if that comparison passes so we can seek two sim dot is a winner and see what's going on there so all that happens here is that stir comp compares two strings word R is being nice to us again and showing us the string that's referenced to 3 ei 5 is our second correct input so I can go back over to where we're interacting with the binary and then run it again for our first input it's 1 337 and our second input is 2 3 ei 5 and we

get you win instead of fail awesome so what did we learn we learned that string cross-references are incredibly useful for finding related code to whatever prompted is that we're seeing return values are always in EAX and the order the arguments are pushed onto the stack from right to left having done some simple reversing let's try our hand at somepony I'll introduce some examples here all of these will be available as examples to you guys afterwards so stack overflows are mostly dead now but they're still worth mentioning in this example an out-of-bounds write allows the user to write to a local variable what you should see here is that hex 10 is the amount of input that's allowed

from F gets and then we've only allocated 10 bytes in the buffer so because arguments are pushed on top down we're allowed to write to I format string bugs exist where programmers allow the user to specify the format string that printf or one of its sibling functions take they allow one to read information from the stack or write to it with a % end modifier in this example shown here notice that I'm reading data off the stack hex encoding with the % ex modifier so as my buffer I just enter in the format string because my inputs pass directly to printf and i get raw data off the stack in this example I'm showing a

trick called a direct parameter access so I noticed that the third piece of data that I got off the stack started in 804 8 which is in the code segment as you practice you'll start to see that and so I can access that directly since it's the first since it's the third piece of data that I got off the stack I can just provide 3 as the direct parameter wild puppies are an increasingly common bug class now they exist when a programmer doesn't account for cases allowing an attacker limited control over the size of a copy or when the programmer simply allows a complete copy large enough to cause a fault yet this example will be available to you

guys afterwards use after freeze exists where programmers it forget to set references to allocated data to null as you guys pointed out earlier after freeing them allowing references to be reused in conjunction with this it's worth mentioning how malloc organizes allocations on the heap the malloc algorithm used in this particular brand of Linux shows shown here illustrates this so allocations are organized according to size there's like you can imagine bins like there's very small small medium large huge so in this example I allocate 20 bytes and then I free it and allocate 15 bytes in free and over here you see that the same address is reused to allocate those two pieces of information alysus there's a

lot of tools but showing here some of the most popular ones on the left is Ida this is like a premier static analysis tool it's awesome because it's got a really great decompilers the industry standard for analyzing disassembly on the right this is Voltron which is a it's a gdb in it you can think of it as like kind of a visual front-end to gdb you can organize panes so there's a break points pain there's a back-trace pain and registers pone tools is generally used for connecting to and interacting with remote services but it's useful for so many purposes surrounding the process of exploit development in the screenshot the user is testing some shell code and

interacting with it notice at the bottom there's the result of ID which shows that we're the zero cool user and here's the command ID check suck is a helpful tool for showing which exploitation mitigations are explore enabled in a given binary so notice that the NX is enabled on this binary so basically all the data segments are marked not executable so stack heap data segment so what what now well I provided some challenges and a bigger inbox for you guys to play with take a picture of this slide if you guys want to play around with some of the examples that I showed and in return for write-ups on these challenges and a few extras that I've

thrown in there I'm giving out books you guys send me a good write-up that I can tell wasn't just copied off the internet I'll gladly reward you guys with a book yeah there's extra poni bowls too that I haven't shown in my slides you guys want me to go back sorry

alright and I'll make the slides available afterwards do so how about bypassing mitigations want to be there right so let's try up own challenge so we're gonna go back to this bears example get control of my mouse okay so I'm interacting with the binary in this pain basically I made a binary and it printed out its address just remember it ends in 0 or e zero zero eight here I'll make it bigger for you guys in the back oh wow this is not it's on my screen geez so sorry y'all better okay alright so we made a we made a grizzly bear and then now it's waiting for us to do something else so how about let's try

one of one of the questions I asked you guys was can we delete it and then reference it again just for those of you who don't believe me let's delete our grizzly and then print it so printing still worked we got five months or one one-month hibernated rather so what happens if we create a polar bear in its place so that same address ending in zero zero eight was assigned to our polar bear that we've just made now if we fill in the fields and then do our grizzly print again what happens well we got this really crazy big number of months hibernated so what do you guys think that is here's a hint so the months hibernated is 20 bytes

into the struct see that sixteen and four and see what's at that same location for the polar bear it's the function pointer so we just leaked memory we now know where the function is in memory so how can we use that well the offset between the print polar bear function and our secret admin shell function always stays the same so if we just know the difference in those two locations in memory then we can calculate the location of the secret admin shell in memory as well and then we can create a new grizzly with a with that with that address of the secret admin shell function as its hibernation as a number of months hibernated and

then we can refer to that grizzly as a polar bear since those references can get mixed right if we delete a polar bear and then allocate a grizzly and it's in its place then that reference to the polar bear still exists if we print our polar bear after that it'll use the address that we've provided it so let me try this out so if I make a new polar bear and then fill in the fields really quick delete it make a grizzly in its place and then fill in the fields so it's asking for the number of months hibernated we just need to take that number that we leaked out calculate the difference which I'll

do over here that is the address of our secret admin shell so now if I print that polar bear I should get a shell

[Applause] thanks all right so we pwned it by the way there's another bug in that binary so there's something left for you guys so here's some super helpful resources that help have helped me in learning Gonville is dragon sector team member one of the best CTF teams in the world he does like write-ups and you know for like CTF sub all skill levels super helpful live overflow is pretty similar something I thought it was really cool is I were like the guy who does live overflow went over the the new Nintendo switch bug the arbitrary code exec so that was like really fun to watch rpi sec MBE is where i learned most of this

stuff it's a free online class that teaches binary exploitation it's incredibly awesome challenges dari and potable tw if you just want more reversing and pointing challenges a bug hunters diary if you guys are interested in actually like making a bug hunting career out of binary exploitation I highly recommend this book walks through everything and that's all the time I have thanks to everyone whose work I ripped off just kidding it's the only inspiration thanks especially to Richard Weiss and Mike Pizza cynic Rico butts my mentor who is definitely bored with my talk by now [Applause]