← All talks

Exploiting Classic Stack Overflow, By Owais Mehtab

BSides Islamabad51:52157 viewsPublished 2020-11Watch on YouTube ↗
Mentioned in this talk
About this talk
Owais is a security consultant having over 7+ years of experience in Cybersecurity domain. He has provided services to multiple entities ranging from Government organization to financial institutes to Oil and Gas industry. His core area of interest is penetration testing, application security and incident response. Getting shell from Metasploit is great but ever wondered what goes on behind the scene and how the exploit actually works. This talk is all about vanilla exploit development process from finding a crash to getting remote code execution to the challenges faced during the development of a fully working exploit. This talk focused on classic exploitation techniques exploit mitigations such as ASLR,DEP,SAFE-SHE etc.. are not covered due to time constraint. BSides Islamabad website: https://bsidesislamabad.com Twitter: https://twitter.com/BsidesIslamabad Facebook: https://www.facebook.com/BSidesIslamabad LinkedIn: https://www.linkedin.com/company/bsidesislamabad/ Discord: https://discord.com/invite/ZPbJVv
Show transcript [en]

[Music] [Applause] [Music] uh today we have uh one of my one of uh the person i always look forward to learn about uh when it comes to uh pioneer exploitation or weber exploitation an awesome fellow uh contributing towards the community and now presenting here at bayside islamabad um a west metal who works as a security consultant be speaking about exploiting classic stack overflows so what i guess andrew self and do your thing all right thank you everyone and thank you everybody for organizing such a great event and letting me participate and be part of it and so i have basically a lot to talk about and i will be skipping a few things and uh slides are there if you if you want

to follow along so uh the thing uh topic i'm going to discuss about basically demonstrate about is basically about exploiting classical stack based buffer flows and uh i will just skip a few slides like uh the boring one about me or who am i i'm just going to skip that all along and then we will just uh hop on towards agenda and what's the engine for today so basically understand what what is uh buffer overflow and why is it cause what what what could happen if a buffer flow occurs why why it occurs and then we will uh quickly look into the prerequisites for understanding such uh exploits and like understanding how the assembly works and what are sections uh how the

instruction works uh things like these so uh just a little bit about stack baseball for overflow uh what it is is when you provide when you start a program and then let's say the program expects some input from the use then we provide uh overly long uh string or some sort of data that program cannot properly handle uh the program would eventually crash and then depending upon the conditions and it can result in denial of service it can result in arbitrary code execution and things like these so uh we will quickly look into some of the assembly assembly things and develop a basic understanding of how things are working behind uh so basically there are multiple

sections for our program and then we are going to look into the data section text sections vss rsrc relog so basically uh the data section is used for initializing data or constraints this does not change over the time and the bss section is used for declaring variables for for a program the tech section is where the actual assembly level code resides and we will look into some programs uh how they look and see and what they look like when they when they get compiled into a windows binary and we will we are just going to talk about a little bit about the registers because uh these are a few important things to know about before diving into a stack

overflow so uh here we are just going to focus on the general purpose registers and basically there are like multiple types of resistors general purpose registers and segment registers so uh general purpose registers are ax ecx edx and ebx esp ebp esi ada and so eax and edx basically are used for arithmetic operation and ex usually holds your written value as well for example if a function is called and then it is performing some action and returning some value e x is the register that is going to hold that value uh similarly ecx is basically used for loop based operations or or for counting uh ebx is a basically a pointer to the data and ebp

is basically a base pointer it is a frame based pointer and then esp is also a stack uh frame point uh stack pointer which basically uh points on to the top of a stack uh so a few things uh to remember about ebay ebb plus something is always argument uh for the function and ebb minus something when whenever we see is usually the variable uh the local variable of the function yeah so these are uh the registers uh we we usually see in like 64 and 32-bit and 8-bits processor so uh for now uh we we have like if we have a 64-bit architecture or if we have a 64-bit system and these are rax rcx rtx

uh similarly we have um 32-bit uh register that is eax and this is the same register but it is referred to as ex ecx and edx uh similarly if you want just to access the first 16 uh bits of the register we can use ax similarly if you just want to access the first four bits of the register uh of eax we can use al and similarly if you want to access uh specific by uh bits of the register of like from fourth to seventh bits or uh four through eight bits and we can use ah and similarly for other registers as well but not all of the registers can be accessed in in chunks uh

only the mentioned one can be accessed in such a way for example uh if you notice here edi adi can only be accessed by di and dil uh but not npih or something else so uh a few things to keep in mind uh uh when looking at the assembly instructions so basically uh if you look here uh the first instruction is basically moving the value one two three into uh register eax uh the next instruction is very similar but here's a catch and basically it will move uh whatever it will first look for the value in eax go to that memory address and and then copy one two three on that memory address for example ex

contains in this case and on the second instruction if the value of eax is 1000 what the program will do is go to the memory address 1000 and then copy the value one two three on address one thousand similarly add instruction here so what it will do is whatever the value is in ex it will add one in it and save save the result in eax as well so the next instruction here we have is add eax and then square brackets one two three four five six so what it will do is is basically uh go to the instruction one two three four five i'm sorry so it will go to the address one two three

four five six and then uh pick whatever value is there and then add that value into the value of eax similarly uh the last instruction we are going to look at is is move eax and then bracket square brackets uh what it will do is go to the address one two three four five six and then copy the value whatever is present on the address one two three four five six and then copy that to eax all right so um the program we are going to look at uh are basically using standard c serial from uh calling convention and then we will if you have any queries about uh calling conventions we can uh you you can uh drop down uh

through the squad channel or the youtube chat or whatever you find easy so i'm gonna skip it and then let's look at this diagram so basically uh let's say there is a function and that is calling another function what it will do is it will basically say written address evp and then here it is basically pushing the arguments on the stack and then when the next function is being called so it would push the ebp and then basically the base frame pointer so once that is pushed it will start it will start virtually a new stack for for the function that that has been called uh and then once the function exits it it will pop the

value of ebp that is saved here uh back into the ebp and then clear up the stack and then once that value has been popped out it will return to the address so basically whenever function is uh function returns it is uh basically something like a leave and then followed by a written instruction so it basically leaves us the magic of like clearing up the stack that is that that is used by the current function that was called when exiting so we will look at another diagram to elaborate things a little bit further so this is let's say this is the main function and it has some variables and then some arguments being pushed and then the sum

function is being called and finally it is written in value zero so basically here whatever is represented in the red is is the stack of the main function and whatever is represented here in sort of yellow color is represented is representing the stack of the function sum so again remember ebp minus something is is a variable for for this function and then and ebp plus something is always the arguments for this uh the function that has been called so uh we will look into the code and i'm just going to minimize the slides and then because i strongly i believe if i'm just going to narrate all the slides it won't make much sense rather

than giving a live demo everything is documented uh in the slides step by step and then we will just uh do it live here instead of like going through those slides so if you have any queries questions uh please feel free to shoot on and the the youtube chat box or the discord server uh and i would be happy to answer to the best of my knowledge and let's they can do the first program uh some some dot cpp so here we are basically defining some headers and and what not then we are describing a function that is returning a value integer and it is expecting two integer values and then the integer x and integer y are

basically the arguments and then we have here uh another local variable being initialized not being initialized is defined and and then later on we are storing the sum of the two arguments uh in that variable and then calling three printfs here and and then returning the value z uh variable whatever the value is stored in variable z and here we have the main function the program always starts with the main function keep that in mind so here we are initializing two variables i and j as 0 and then assigning the value 10 and 15 respectively and initializing another variable k as 0 and then calling a function sum and then whatever it will return we are going to store that value in the

variable key and then finally printing it out so this is how the program looks like uh in nc finally before switching to ida to look into how it looks like at the assembly level i would like to point out that this main function is also returning value integer value and that is zero so i would just quickly open it in an ida and then look for the main function so this is basically what the main function looks like and this is where the stack is being set up for the main function and and here we are initializing the variables to zero then assigning the values uh 10 and 15 respectively then then we are doing some some more variable

initialization and then we are moving the value for one of the variables into eax and then pushing on to the stack the value of ex and then moving another value from the stack into ex and then pushing that somewhere and then finally calling and the function so probably it would not make sense right now but if you look in it through a debugger it would make much more sense so here our ida has renamed the function but in the comments here we can see this is indeed the sum function and we will just quickly go back here and just look at the addresses so this is where the function main function is starts and then uh we

will set a breakpoint a few breakpoints and then we will continue the execution from here in immunity so basically this is a debugger to debug a program i would just quickly load the program using by pressing f3 and i would load the executable foo so before uh like looking into these areas i we need to set a few break point i have already configured the breakpoint so how do we configure the breakpoint we just need to type bp and whatever the address we need to break it so on the typical as soon as it reaches that specific address it would uh pause the execution so i would just go and look um addresses where i have put the

breakpoint so i can press control b and here are the list of the addresses that we are going to pause on so i will just quickly go back to this assembly view this is this is basically our debugger this is the disassembly view this is the registers view this is the stack view and here we have the hexagon that is basically the memory done so i would usually program stops at the entry point we will let the execution continue and now we can see that we are indeed at uh the first instruction sorry i loaded uh just quickly exit my debugger and unity three sum so i'll just repeat the same stuff i've already configured

so if we look here this is exactly the same thing as we saw in ida here

they push abv movie sp and something and something and then followed by a call and these are the instruction so if you look here we can see all of the instructions are there we are paused currently at this instruction as we can see eip eip basically contains the address of the next instruction being executed in this case it is calling a function so i'll just quickly step over so basically there are there are multiple types of stepping stepping into the means that execute one instruction and step over means that for example if a function is being called so what the difference will do is rather than going into the uh taking us into the function it would execute that

entire function and then written once that execution is done so this can be done by pressing f8 or from this menu and then step over and so i would just press f8 and we would see that we are indeed here so here we have this stack currently it is pointing to this address so if we look here what this instruction will do is initialize the variable value to 0 as we just saw in the c code these variables are being initialized and we will just quickly look into immunity and see what it is doing so notice here there is only one zero on this address so if you do the math e f e h zero plus one

c is a f e nine c that is this editor and this contains right now the value 21 if we step uh into this instruction so this address now contains zero so similarly f e a plus one eight would be this address and then if you step over and see now this value on this side is also contain zero so now the second and these two instructions are basically assigning the new values 10 and 15 respectively x and x equivalent of 10 is 0 a and x equivalent of 15 is basically zero f so i would just quickly step over and notice these values have indeed been pushed and now this is where our third variable is

being initialized and as you can see here and now we are moving whatever the value of uh variable i is being moved to this register notice the value uh ex has one it will now contain variable f so it is moving basically the second parameter and then pushing it on on the stack and if you look esp so basically this would be the address so here we can see ex has indeed been pushed and then now we are preparing for the first parameter because uh the seed calling convention basically takes the parameter from right to left for so it will push the rightmost parameter on the stack then the next parameter and then the next parameter in in our case uh the

function sum here was only accepting two parameters so it is uh going to push the next parameter or the first parameter on top of the stack that is this instruct this address so uh if you step over we can see quickly that indeed these two values have been pushed on top of the stack that is and now we are calling the function sum so if we step into uh this function that is in actually some what will happen at the background is if you notice here double zero four zero one five nine nine that will be post here and uh then ebp will be saved when when we are actually into the sum function so uh

what we will do is uh quickly step into it and then notice uh four zero one five nine nine uh being pushed here as uh here so here we are and now it is in this function the sum function is basically setting up its own stack so uh it is saving the ebb as we already discussed now it's setting up its own stack and now adding some values so we will quick and notice that this value will be moved down quickly as you can see somewhere here it has been pushed down and now we are looking at ebb plus something and moving into the register e x and e x so yeah it is uh referring to abb

plus something and ebb plus and remember ebp plus something uh is uh is referred to as the function argument whenever we see something it is referring to the functions argument so if we uh step into so we look at the value of e d x indeed it is uh uh it is containing the value of the first uh parameter and if we uh step in again a e x contains the value of the second parameter that is 15 and and then adx contains first parameter and e e x can so at this stage we are just basically performing so uh it will store the result in eax and this is what it looks like say in hex

and then if we look here the function is still not showing anything it is playing any any kind of output so basically we will just uh continue execution till here right before the call to print f and then we can see some values have again been pushed on top of the stack before calling uh the function printf and we can see in this case printf is expecting two arguments the second argument is is basically the format is specified the first argument is basically the address uh which which contains the string argument one and if we go at this address in the memory tab it indeed contains the string argument number one so we will just

quickly step over and look at the program so it will quickly say that argument one is this and what and similarly what we are doing here is is again calling printf and then and and i would just configure this breakpoint here and then pause the execution again here and it would basically it is pushing the address of this instruction and then pushing uh as the second argument is being pushed as uh basically whatever we passed uh to the function and that is value 15 and then if you step over on that function again by pressing f8 we can see indeed that the second value the second argument value has indeed been printed so we will continue then

execution up to this point by pressing f9 and then step over and we can see the sum of the 24.25 is exactly and we are here in the code and finally we are returning so remember i told you about uh ex contains the written value notice eax contains 1c right now if i just step in and now ex contains the value 19 that is the equivalent of 25 and decimal and basically now look at the leave and remember the 599 value uh somewhere pushed here if we just start one more time so yes this is the address of the instruction we we saved on the stack before calling the thumb function and then basically now we are just returning to

the address and then whatever it's on the top of the stack it will return to that record so if you press f7 again back into our uh clear main function so i would just quickly uh go through the we are here so ex is being pushed uh to esp 14 this this time that our compiler has done some uh tricks and tried to fool us around but basically if you look here it is basically referring to the variable k address so uh if we notice here esp plus 14 it's probably this address and if you step over it is basically containing hex value 19 that is equal into 25 and then due to the lack of optimization it is

moving back and forth the same value over and over again and that is moving ex to and sorry this is this is basically these two instructions are basically preparing for the arguments of uh f function again so it is pushing the second argument and this is pushing the string value so if you look at the code uh here this is the address of this string would be push and then the format is by the specifier or the address of the variable k will be pushed so i would just quickly step over step over step over and we can see here and we are here and we look at the program

here

and something is not working so just quickly restart the program and i would just step over a few

and i will just quickly go over this function that is basically printing this line so you can see the value returned from the function is this and blah blah blah so now the main function is uh returning value zero and exiting so if we step over uh ex contains zero and leaving and then if you follow along a little bit more it is basically calling exit and to exit the program so if we here and we can see the process has indeed been terminated so now that we know how the function is being called and how it looks like when the parameters are pushed for a specific function we will look at another example uh

[Music] okay so we will look at another piece of code that is food.cpp so it is a basically we are here we are defining a function full bar that is not taking any input not returning any value just printing a value you have read this secret function and then calling and then some other function but remember uh whenever we start a program it always executes name function and we don't see any call to foo bar in the main function so it wouldn't this function would not get executed at all uh so let's look into the main function here we are defining uh character area of 32 points another character of 16 bytes and then we are

printing something and then we are taking input using f gets then we are equaling it back to the user and we are saving the that the user input in this buffer one and then equaling it back and then we are printing this string and then using a scanf to take the second input and then be going it back and then returning zero so we will quickly uh look at how it looks like in ida probably yeah so this is the main function as we can see there is no call to full bar and then this is how it looks like in the graph unit it looks like how it looks like in the text stream

so we are going to set up a few breakpoints and especially on this function this one decided this address and then we also would like to notice the address of 4 bar but not here what i will do is load this thing in immunity and function to all right so i would uh like to point out this address 401 for fa as this will be referenced later on and and as we can see the function foo bar is indeed here and here we have the main function if we want to confirm this is taking the first input this is taking the second input which confirms that this is our main function so i would just let the execution run

and until we hit the breakpoint so we are on the main function now if we step over quickly a few things so basically we are pushing on top of a stack at this address and then printing it out so if you step over and then we can see and print def has been called and then program is basically saying input number one and then we are setting up some parameters for for this function so what i will do is i will quickly uh reach to this function before reaching to that this function a few parameters have been uh configured here if we look at the first parameter so uh we need to follow this one in down

this address contains some garbage and data and and this is basically specifying the size the 32 byte and 32 bytes and then this is something else and then i would just let the execution run and if we type maybe cd

and the function returned and now we are configuring some parameters for printf again to print this string and then i'll just step over quickly and i will go into the details of this printer function again and then we are just basically printing and pushing the address of input number two and then calling printf and here we can see this is uh our input has whatever the user provided has already been equaled out and then another printf has been made uh where i stopped which says input number two so basically the previous printer function we had was just echoing out whatever the input we the user provided and now we are setting up parameters again for the scanf function

uh here and i will just quickly ram here is my execution my execution pause here so scanner function is being called so if you look at the address of this kind of let's go to the expression

follow address in dump it's probably this

and sorry this was the address so if we go to the address it indeed contains our string so now uh this is where uh the program is exam exiting the function sum so i would quickly go over it and it is finally printing one more print that we mentioned that is whatever the second input of the user provided to the program and then moving value zero and then returning so notice uh before calling that function we saved the written address and then we will probably written back somewhere here and then press f8 sorry this was which we saved and we are returning to this address and then we can uh the program is exiting right now

so uh let's restart the program and if you are following along with the slides so we are basically on slide number forty five

[Music] and we will restart the program and then what if we basically provide more than 32 bytes and to the first input what will happen so let's uh figure out and let's uh send 64 a's instead of like 32 a's to the

return to this address if you remember uh keep this address and zero zero six one f eac right now it contains some some written address and then if you provide overly long string and press enter so this is still contains something and but if we gradually continue f9 to this point it won't ask for the second scanner and i would probably

if we look here now it contains one for one now the uh now we have uh uh basically overwritten written address of one one of the function that was being called so if we let the execution continue the program will not ask for the second input rather it would just go lost and then finally we have uh eip containing 41.1 and then indeed the program did not ask for the second input and instead it just overflowed into the second input whatever we provided in the first input this is where things get interesting so um now we can see that we can control eip and if you remember remember eip contains the address of instruction that is being executed if

you can control eip we can control the flow of the program so we will quickly restart it and and remember the address of the foo bar function this is the address and if we hop somehow manage to hop over here the program will continue the execution from there and then go to this point but we have a few challenges that is and this program is being loaded in it starts in address that starts from zero zero uh zero zero is basically a string uh terminator terminator uh or the null byte and null white basically terminates uh the string so what can we do in this case we can uh get over uh get around this problem by

partially overwriting the eips as you can see the eip also already contains zero zero in its most significant uh byte and we just need to partially override the eip instead of like completely overwriting the eip so we will just overwrite three bytes in ei okay with that in mind uh we have to figure out how much amount of data is exactly required uh to control eip so for that we have uh something called nutri analysis what i will do is instead of sending 64 bytes of a i will present what's away followed by 32 bytes of b and then see if and the eip contain b's so i would just split the b and into eight eight bytes

of air bytes of b and yet and eventually i will figure out how much bytes are exactly required so i would just quickly go through this function and then just provide a demonstration for this one and see the erp contains b so we will continue splitting it up to this point for the sake of time i'm just going to copy the last string and then this program is input so if we throw out this one and continue the execution by pressing f9 we can see indeed that it contains four five four five four four four so that means uh you we need exactly 59 bytes of case or exactly 59 bytes so in order to confirm

our theory we can check this check this thing and that this string contains basically 59 a's and then followed by 3d so it should if you provide this one uh eip should contain zero zero four four four four four four and let's restart the program by pressing ctrl f2 and pressing f9 a few times again and providing the import and there we go and then let's see indeed it contains zero zero four four four four now that we know how to precisely control eap uh remember that address let's look into the exploit code and what is this export code doing it is basically creating a file label.txt and then we are concatenating the address but

due to the indian-ness and that the intel cpu follows we have to flip the bytes and then we have to write them in a reverse order so zero zero four zero one uh four f a is written as f a one four four zero so i would just quickly demonstrate uh this one to trigger that function uber

so it is basically creating level dot txt and if we pipe that output in dot exe it would it should trigger that fubar function that was not never called c and we can clearly see that we have indeed been successful in triggering a function that was not there so this demonstrates the power of a stack based buffer flow but this is not something very interesting uh rather i would like to show uh [Music] something more interesting and right now we are at slide number 74. so now that we have covered pretty much uh a lot of information about uh overflows i would just quickly uh demonstrate exploit against against a real world application and basically what i'm going to do is start

with with the crash analyze the crash and then from there onwards you will follow the same process instead of following a predefined function that was a part of code we will try to introduce our our goal and then try to trigger a calculator or try to execute a bind shell so this is uh pretty much in the nutshell what we are going to do is triggering triggering the crash analyzing the crash follow which registers points to our our control data and and figure out how much bias we need to control the eip then find the address for the shell code and sorry find the space for the shell code that we need and then find out what are the bad

characters bad characters is basically and we will talk about it when we are when we reach that point and then find a relevant uh jump uh to that to our controlled area or or the register that is pointing to our controlled uh buffer and then we will place in some knobs and then followed by some shell code that's all pretty much all we need to make a working exploit so let's start so this i'm going to start with the first poc code this is basically creating an evil m3 file appending 27 000 is inside it and then finally closing it so i would quickly go and create one and we can see it will evil m3u has been

created so i would load our vulnerable application inside immunity and we will continue the execution and if we look here at the desktop evil m3u and load here indeed we can see eip contains 414141 and an esp basically points to the address and that also contains our data so now that we know that we can control eip we can again follow the binary tree analysis approach we just followed for the previous program and let's restart the program and let's look at the plc number two so what we will do is we will split the twenty seven thousand of a's into twenty thousand of eight and and then uh seven thousand of these and and then

see what the eip contains so i would quickly delete this uh uc file and i will just double click on pc2 and let the execution run again and let's see okay now that eip contains four to four two four two or the base and here uh that means that as the crash occurred somewhere between twenty thousand for one and twenty seven thousand byte so what we will do is instead of like continuing the binary analysis we would send a unique uh 7000 bytes unique string that and and and figure out where the crash exactly occurred so we can use a script framework to create such a long string and basically it's brighter and create and then followed by the length

so while it is creating that string i would just restart the program again by pressing ctrl f2 and clicking on

here we have the unique string generated so we would simply copy paste it so the new plc code would look like something look something like this one we will again create an eln3 file followed by and it is a pending yeah sure so it is appending a twenty thousand of a's and then followed by seven thousand uh bytes of uh string and then uh this is uh what we are going to create another table m3 file and we will analyze the crash again and now the eip contains this value we will feed this value to by random offset and we will see that it would mention that and this would mention basically 6081 bytes and

let's wait uh in the meanwhile i will restart the program and as you can see exact match is this 6081 so that means uh the exact uh crash occurred at 26 000 81 bytes so our pc code 4 would look like something like this and we will append 4 26 81 bytes of a and then followed by 4 bytes of b so if everything is if our calculations are indeed correct so we would just generate a new poc and let the program run again and eip indeed should contain our base yes and and psp contains our c's so now we have to figure out the shell space we we we have already figured out the exact amount of bytes to control the

eip we will note this address and then follow the esp in dump and we will start looking where the c stops so basically it is stop somewhere here and if we subtract this address from this address uh it would result in almost value 388 or something so one double

that means almost we have 984 bytes and we have 984 bytes of initial code space uh the next thing we have to figure out is the bad characters so in order to figure out the bad character what we will do is create another evil m3 file and then send instead of sending c's we will send a byte array of containing values from 0 1 to 0 x f f um yes we got a lot of questions as well as uh uh feedback from people out there so uh i think if you can just wind it up uh we're getting late yes just quickly winding it up thank you so much thank you so much thank you i really appreciate for

uh giving me a little bit of extra time like a lot more than a little bit of extra time so just let me continue with this one and then we had pse number five here and then we will look at the bad characters here

so the thing what we would do is is follow this and dump again and

and if you follow esp in them we can see that it indeed contains these values and this values so that probably means uh 0 9 is the culprit that is basically breaking our shell code because we could not see anything other than after zero eight so we will just quickly remove uh that character and then continue the execution similarly we will uh remove zero a because usually it is it is also considered as a bad character so we will just restart the application here and press f9 again and delete previous file and generate the poc okay we have this generated here and then we see here vdf you can take this value and esp esp now contains everything we have

nothing breaks here and the next thing we need to is to figure out jump to our uh register esp jump minus our esp we are going to quickly use to find this address and then we will look at the log window by pressing alt alt l and then this is the instruction that i'm going to use so the next poc would look something like this it contains our shell code it contains our jump to uh jump to esp and and followed by some knobs because shellcode sometime needs a space to decode itself and and as you can see here esp basically is pointing in the middle of our byte array not exactly where is it

starting so we we also need the knobs for that thing so we will just quickly generate a new poc

and set a breakpoint bp one double zero one p zero five eight this is where our jump to esp contains so let the program run set the breakpoint again and we are going to use this pc9 to generate this thing if everything works fine so we should hit our breakpoint indeed we hit our breakpoint if we press f7 f7 again and we are landing here on our knobs and if we continue the execution it should pop the calculator indeed it did so that's pretty much it and that i have to share with you guys and thank you again apart for giving me um the extra time i needed and that's all i have to share