Monday, January 16, 2017

Lessons from Pentesting #2

Intro

Heyo folks. So on Twitter I asked a number of you what you wanted me to post about, and a number of you said that you'd like to hear what I've learned from working about a year in pentesting. Well, without further do I'm going to try and explain what I think are some of most important lessons I have learned from some of my recent and past jobs. There is a lot to cover so this post might be a little long but hopefully it will help some of you out there when encountering similar situations.

Lessons

Okay we are going to do this on a mixture of anonymised situation based scenarios which I have encountered as well as some general tips as I can't remember every situation :P

Always Relate To The Client

So this is one of the lessons that I had more trouble with but I had some specific scenario with a client that made me realise the importance of this. I was onsite with the client working a particularly disorganized job where things weren't working out and my technical contact was constantly pulling me off the job for various things such as updates on the testing and meetings with various people. This lead to tension between me and my technical contact as I was not particularly happy with being taken off the job to do these various elements and we were not seeing eye to eye with some of the arrangements that were being made to try get the pentest back on track.

Eventually though, I did find a solution that worked. What was it you ask? I looked at the situation from the perspective of the client. I realized that I needed to stop pushing the job from a pentester's perspective and start looking at how I could try help the company from the perspective of my technical point of contact. This is an important lesson and one I still use on my jobs today as it is important to realize that there is a time and place for being stern and pushing the fact that organizations need to get their shit together, organise themselves to be ready for a pentest, and make sure they fix their issues, but there is also a time to understand that there is a lot that goes on in order for an organization to be ready for a pentest and that there may be a lot of things going on behind the scene that you are not fully aware of that may explain why the organization can't patch that high risk issue you reported or get those credentials that you need to test the web API.

Therefore realize that everyone you work with is just another human trying to do their job. Once you realize that, you'll realize that even managers are just another person you need to relate to, albeit at a different level than an engineer which you might have to relate to on a more technical level. Get to understand the person, their problems, and think about how you can work to solve those problems, and you'll not only help to solve their problems, but you'll likely solve your problems in the process and will speed up your pentest in the process.

Realize That Not Everyone Has the Mindset for Pentesting

So this is more of something that I have noticed from watching people who have left pentesting as a whole, but I would like to point out that some people join pentesting but just don't have the right mindset for it. Now I may be wrong about this to some extent and I could look back on this and ask myself why the hell I wrote it but I have noticed some people who have joined pentesting recently who have no real self-seeking passion for knowledge and that intrinsic passion to learn more and experiment with things to figure out how to really solve the issue.

The problem with this is that your not always going to be able to ask people for help when your on site on a client site. You may have a website that requires some specific method to interact with it, and without being able to investigate, discover the internal details and craft a solution, your not going to be able to fix the issue. A somewhat better example though is that without having the drive to learn more, your not going to be able to push yourself to learn new technologies and exploitation methodologies that will allow you to provide the best possible solutions to your companies' clients. You are then facing the risk the company seek out more capable pentesters in the process, which leaves you with a situation of job instability if the company doesn't think you are doing as good a job as it expects from its pentesters.

This has lead to some people that I know leaving pentesting and going into software development instead; if I am being completely honest, I am really happy that they did. They were clearly more driven by the programming side of pentesting and did not always have the skills needed to deal with variety of customer situations that a pentester inevitably encounters. They did however know how to craft programs to solve a variety of problems, had good knowledge of programming and associated programs, and had the drive to create solutions to common problems they encountered, all things that are well suited for a programming job.

So, yeah that was a bit long winded, but essentially realize that you may end up working with people who are quite simply just not suited to pentesting. You're just going to have to deal with it and try and help them as much as you reasonably can, and hope that for their own sake they may find something that better suits their available skills and makes them happy, as you are not responsible for their decisions in life and ultimately they must make their own decisions regarding their job.

Your Going to Live in Hotels

One thing that I think people don't fully realize is just how much time you may end up spending away from home, family, etc as a consultant. Being a consultant isn't just a 9 to 5 (or in our case 5:30) job. It will require you to travel down to the client on the weekend, work after normal hours to understand that job that you have coming up, or edit the report for a previous client.

In fact this was actually one of things that I have seen several people complain about when they start working as a full time consultant. My response honestly? Get used to it. We have people in our office that I rarely if ever see. Why? Well some of them are just working from home as its too expensive to come into the office, but a fair number of them are onsite working for a client, and spend most of their month traveling between various client sites for associated onsite jobs. Its not uncommon to be fully booked for the month on onsite jobs with no associated "white days" (aka free days where you can catch up on work, do research, or whatever you like within reasonable limitations) for that month.

As a consultant you are expected to be able to travel to jobs as and when clients ask for you. That job could be up in Scottland, it could be way down South on the coast, it could be easily accessible by train, it could be a long car drive away, it all depends. You need to be ready to go anywhere, and adjust your travel and hotel plans to suit situations that may come up (prime example: train strikes, all the 3 star hotels being booked leaving you with only a local 2 star hotel to stay in (happened to me twice)). 

So yeah, if your not ready to be flexible on a daily basis, pentesting may not be for you.

Be Prepared for Things to Go Wrong, and Realize Its Not Always Your Fault

I literally can't tell you about the number jobs where things have gone wrong. From missing credentials, to the client updating the site in the middle of testing, to missing authorization forms, to credentials being incorrect, to documentation not being supplied, there are many things that can go wrong in a pentest. Sometimes you may even feel that you caused all of this to happen and it can be overwhelming at times thinking that you might have forgotten something that you think caused all of this to happen.

The best way to deal with these sorts of situations I find is to expect that you may have to spend a day or a few hours on the first day dealing with issues and trying to get things sorted out, especially if its an onsite job (I find remote jobs typically tend to go quite smoothly minus potential access issues as there is less for the client to deal with in most cases). Be prepared to take an active part in trying to help the client out as it is likely that they may not fully understand what you need to conduct your test so you will have to explain it to them keeping in mind they may not be technical.

Also realize that most times when something goes horribly wrong its not entirely your fault. Sure, there may be some situations where you really did mess everything up, but 95% of the time, its either going to be both the client's and you or your company's fault. This may be because the job was not scoped correctly, because the client didn't supply appropriate details, because there was a lack of understanding of the technology, or any number other reasons. All you can do is try do your best to solve the situations you are responsible for and realize that you are not responsible for everything, and there are things that are beyond your control.


Ask Questions to Colleagues But Only If You Can't Find The Answer Yourself

Whenever you are pentesting, one of the most important things to realize is that your colleagues are around to help you. If you are seriously stuck or need advice about something, send them an email or walk up to them and ask them your question(s). Even managing pentesters still have questions about their job; everyone is still constantly learning and we all need to ask each other for help from time to time.

Do be careful though, as you can fall into a trap of asking questions too often instead of looking things up yourself, and you can end up just bothering fellow colleagues (something that I personally am trying to improve on). Therefore always make sure you have a concrete question you want to ask and that you have tried to look up the answer beforehand. This will prevent you asking questions that are a simple Google or internal website/wiki/documentation/etc lookup away from an answer.

Conclusion

Hopefully that helps some people who are starting out in pentesting. I may expand this more in the future, but this is what I was able to come up with in one night from my recollection of past events and jobs within the last year that stood out to me as being prominent in shaping my day to day activities pentesting or which taught me an important lesson.

Let me know if there are any lessons from your pentests you have learned - I would be interested to hear other people's experiences.

-tekwizz123

Saturday, June 11, 2016

Solving Crackmes: A Beginner's Guide Using LuCiFeR's Crackme 2 and Hopper Disassembler

Intro

So as some of you guys may know, I now work for NCC Group as a Security Consultant doing web and infrastructure pentesting. This normally means that I don't tend to do very much security work outside of that. Lately however, I have gotten the oppertunity to do some more research, specifically with reverse engineering. One afternoon I wanted to do something interesting, and remembered about the idea of crackme's, or small programs that people create to be reverse engineered.

Crackme's usually have some sort of goal in mind. For example, they may ask you to find a working serial for the program, or to remove an annoying popup that appears every time the program starts. Additionally they may have some restrictions on a proper solution. For example they may also state that you can't patch the program's assembly so that it jumps over the function that displays the nag screen and that instead you must find another way to solve the problem.

After looking around at a few crackme's I eventually found one that I thought would be a good, very easy challenge to start off with: LuCiFeR's Crackme #2. You can find the file at http://crackmes.de/users/lucifer/first_c_crackme/. Alternatively, you can download it here if you don't want to sign up for an account at crackmes.de: https://drive.google.com/file/d/0B5pT4hU_yYUWeXFvS2RLeDhoTWc/view


Tools Used

To solve this crackme, I originally used OllyDBG and BinaryNinja. That being said however, BinaryNinja is currently in beta and after testing it for a while I found I really don't like it's limitations, such as not being able to search for cross references to a string. Because of that, for this tutorial I will be using Hopper Disassembler. You can use the demo version or the paid version for this tutorial, though I will be using the paid version as I have a personal license. To download Hopper Disassembler, simply visit  as well if you want, which is available from http://hopperapp.com/download.html.

Keep in mind the demo version of the application has a 30 minute limitation on sessions and you cannot save your session. This is similar to the free version of IDA Pro with the exception that with IDA Pro's free version does not limit the session's length. If you don't want to pay the £70 for the full version of Hopper and you want longer sessions, but don't mind not being able to save your work, then you can also do this in IDA Pro's free version.


Initial Analysis

To begin our analysis of the crackme, lets first read what the readme.txt file contains:
  • Rules:
  • 1. Do not Patch
  • 2. Sniff a serial for your name
  • 3. write a keygen
Okay, so looks like this is a serial crackme where we have to find the serial to make the program work. Additionally we have also been told that we cannot patch the program to disable any checks, and that we need to write a keygen. For those of you that are not aware, a keygen is a small program, written in whatever language you fancy, that will take in some input, such as a name, or some other input, and generate the correct corresponding output, such as a serial, for a given crackme.

With that in mind, lets run the crackme and see what we have:

 

Okay so we have a few things to note here. The first thing is that the program displays a menu. We should note this down as we may want to look through the program's strings in a disassembler and see if we can find any cross references to these strings in memory. This will then allow us to determine the corresponding function that prints the program's menu, which will help us start to analyse the program's execution flow.

The other thing to note is that the program seems to be taking in a name and a serial as input. Based on the fact that the error message that is returned says that we have not entered the correct serial, it seems reasonable to make a guess that the program could be taking in the name as input into some sort of serial generation function. The serial that the user enters is then checked against the output from this function, and if the serials do not match, the program displays an error message and terminates.

Now that we have done an initial analysis of the program and it's functionality, lets load it up into Hopper and examine it. Drag the executable into Hopper and accept the defaults to load it as a Windows PE file. Once Hopper has finished it's analysis, you should see something like the following:

 

You may not be able to see it above, but Hopper has dumped us at the program's entry point, which it has helpfully denoted as the function EntryPoint. On the left we can see a whole bunch of functions, however none of them seem to have any helpful names.

There's a few ways to solve this issue, but the way I like to do it is by looking at the program's strings. To do this, click on the button on the upper left next to the Labels button labeled Strings:

 

Hey, would you look at that! There's several strings which appear to be from the program's menu. Lets see if we can find which function they are being used in. To do this, first double click on one of the strings that were printed within the menu. You should see something like the following:



If you look to the left here, you can see hopper has helpfully provided several XREFs for each of the strings to let us know where they are being used. As you can see in the screenshot above, it seems like function sub_4014e2 is using all of these strings. Lets see if we can't examine this further. To examine the cross references for a particular string, single click on the string from the listing shown above (any one will do :) ), and then hit the x button on your keyboard:

 

Ok, now in addition to the location of the cross reference, we can also see the specific instruction that references the particular string we chose to examine. To go to the corresponding function, simply hit the Go To button. This should give us the following:



Looking at the assembly, we can see there are several strings which appear to be loaded into the variables var_424 and var_428 before the function sub_431fe0 is called, presumably to print the string out to the screen. Lets rename these variables and the function to make it easier to read the disassembly.

For starters, lets rename sub_431fe0 to print_buffer_to_screen. To do this, click on the function sub_431fe0 within the disassembly, then hit the n button to rename the function:

 

If we look at sub_432880, we notice that it seems to be being called every time that the program expects input. We can assume that this function grabs the user's input and saves it to a buffer, so lets rename this function to grab_input_into_buffer. When we are done we should get something like the following:



The next thing we want to do is analyse what is being done with our input. To do this we need to focus on the calls to grab_input_into_buffer. Lets take a look at them:

 

What we can see here is that EAX appears to be loaded with the location of a variable in memory (this is done via the LEA instruction). In the first call, this is var_108, whilst in the second call this is var_208. This address is then placed into var_424, which appears to serve as a pointer to the buffer in memory where our input should be stored. Following this we see that for both calls, var_428 is passed the parameter 0x437510 prior to the call to grab_input_to_buffer. Combining this all together and using Hopper's helpful comments in green on the side, we can determine that var_428 is the first argument to grab_input_to_buffer, which contains the stream number to grab the user's input from. The second parameter is var_424, which contains a pointer to the buffer in memory where the user's input is to be stored. This allows grab_input_to_buffer to effectively grab the user's input and store it in memory.

Finally, if we look just after the second call to grab_input_to_buffer, we can see a call to j_strlen along with the parameter EAX, which appears to be loaded with the address of var_108, or the buffer where our name was stored earlier. Lets see what the program does once it has calculated the length of the name that we inputted into the program:

 

First, the program loads the result of the strlen call from EAX into EDX at 0x00401676. We then go ahead and multiply EDX by 0x875cd, storing the result in EDX (the first parameter to IMUL is where to store the result, the second one is what to multiply 0x875cd by :)  ). Once that is done, we move 0x51eb851f to EAX, and then execute mul edx.

What is important to note at this point is that the mul instruction multiplies EAX by the parameter provided and stores the result in EDX:EAX. That is, the higher 32 bits of the result are stored in EDX, whilst the lower 32 bits of the result are stored in EAX.

With this in mind, the next instruction, MOV EAX, EDX stores the higher 32 bits of the result into EAX. The instruction SHR EAX, 0x5 then shifts EAX right 5, which is equivalent to dividing by 2 ^ 5, or 32.

Once this is done we multiply the result by 0xfffffc90 and store it in EAX. Keep in mind that any result over 32 bits will be dropped at this point. In other words if we end up getting a 42 bit number as the result of the multiplication, the first 10 bits would be dropped and only the last 32 bits would be saved in EAX.

Next we move 0x0 into EDX and push the values of EDX and EAX onto the stack. I do not know why this occurs as it does not impact anything and the values are not POP'd off the stack at any point.

Following this, the instructions at 0x00401697 to 0x004016aa do some instructions with floating point numbers. We'll get into this with OllyDBG in a bit but for now just now that there is a seperate stack which is used for floating point numbers and these instructions use that stack to adjust our calculated serial somewhat.

If we look at 0x004016ae to 0x004016bf we can see that we load the string "%i-x019871" into var_42C and the address of var_308 into var_430. These are then used as the first and second arguments respectively for the call to j_sprintf, which seems to save the serial that we should have entered into var_308.

Finally, we have a call to j_strcmp which compares two pointers to string buffers to see if their contents are the same or not. The first argument points to var_208, which holds the serial that we entered into the program. The second argument points to var_308, which holds the serial that we should have entered. The program then jumps to a goodboy or badboy message according to whether or not these two buffers matched or not.


Initial Overview of Crackme Algorithum

At this point we can determine the algorithum works as follows:
  1. The program calculates the length of the user's name.
  2. This is then multiplied by 0x875cd.
  3. The result of this operation is then multiplied by 0x51eb851f and the higher 32 bits of the result are saved.
  4. Bit-shift this number right 5 bits, effectively dividing by 32.
  5. Multiply this value by 0xfffffc90
To figure out the final part of the algorithum (so we can generate a working solution) we need to turn to OllyDBG.


Using OllyDBG to Solve the Floating Point Instructions Issue

With a understanding of most of the crackme's algorithum, we now turn to OllyDBG to understand the floating point instructions and how they change the final serial that is generated.

To speed things up a bit, first set a breakpoint at the address 0x00401623, which is hit after the first part of the menu is printed out. If we scroll down we should see the same disassembly as in Hopper, with the first floating point instruction occuring at 0x00401697 after the PUSH EDX and PUSH EAX instructions. Let's put a breakpoint here so we can examine things further, and press F9 to continue the program. We enter in our name, and our serial, pressing F9 to continue the program as needed before eventually we hit the breakpoint:

 

The next instruction, FILD QWORD PTR SS:[ESP] loads a QWORD, or a 64 bit number, from the location pointed at by ESP, and puts it onto the FPU (Floating Point Unit) stack. This can be seen in the following screenshot. Notice that ESP holds the value 0xFE8BC1A0 while ESP+4 holds the value 0x00000000. As we are reading a 64 bit value into the FPU stack, we read both of these values (a 32 bit, or DWORD read would just read the value at ESP, 16 bit, or WORD read, the SP register, etc etc):



An important point to note here is that the value 0xFE8BC1A0 is the value calculated from the first 5 steps of the algorithum that we have examined so far. Moving on though, we can see that the MM7 register of the FPU stack has now been changed to hold the value 0x000000000FE8BC1A.

The next instruction, LEA ESP, [ESP+8] loads the address of ESP+8, which holds the name that I entered into the program (in this case "Grant"), into ESP. This effectively moves the stack pointer so that it now points at our name on the stack.

The instruction FSTP QWORD PTR SS:[LOCAL.260] pops the QWORD value 0x000000000FE8BC1A off of the FPU stack and writes it to the local variable LOCAL.260. If we look closer at the information provided by OllyDBG, we can see that LOCAL.260 is the address 0x0063FB30. Following this in the dump (right click on the address in the information display and click Follow in Dump) shows that the memory is currently empty:

 

We can also see that OllyDBG tells us that the float value 4270571936.0000000000 will be written into memory at this address. Pressing F7 to do a single step in OllyDBG, we can see that the memory has been adjusted, though not quite in the way we expected:

 

Whats happened here? Well, this took me a bit of research and I had to look at some previous answers to understand what happened here, but apparently the FSTP instruction, when converting the number 0x000000000FE8BC1A to floating point number, or 4270571936.0, also packed the number into binary format before storing it in memory. Reversing the bytes, this means that the number is now stored as 0x41EFD17834000000 at 0x0063FB30 in memory.

The next two instructions FLD QWORD PTR SS:[LOCAL.260] and FSTP QWORD PTR SS:[ESP+8] first load the value of LOCAL.260, which is now 0x41EFD17834000000, onto the FPU stack, and then POP that value off of the FPU stack and write it to ESP+8.

MOV DWORD PTR SS:[ESP+4],00401469 moves the string "%i-x019871" into ESP+4, and the following two instructions LEA EAX,[LOCAL.194] and MOV DWORD PTR SS:[ESP],EAX load the address of LOCAL.194 into EAX and push it as the first argument. We then see a call to sprintf with these three parameters. From this we can conclude that we are sprinting the resulting serial into memory at LOCAL.194, and that the string "%i-x019871" is the format string to print into memory, whilst LOCAL.260 is the value that will replace the "%i" part of the format string before it is placed into memory.


Final Crackme Algorithum

From this, we now have our crackme algorithum. We also know that the generated number is appended with the string "-x019871". Our new algorithum now looks as follows:
  1. Calculates the length of the user's name.
  2. Multiply this number by 0x875cd.
  3. Take the result of this operation, multiply it by 0x51eb851f and take the higher 32 bits of the result.
  4. Bit-shift this number right 5 bits, effectively dividing by 32.
  5. Multiply the resulting value by 0xfffffc90, and store only the lower 32 bits as the result.
  6. Take this value in hex and convert it to a floating point decimal number, then pack the result in binary format.
  7. Convert the number back to an integer, and append the string "-x019871" to it.

The Keygen

The last part of the challenge asked one to generate a keygen for the program. This is a small program which takes the algorithum mentioned above and generates a serial based on the name entered. I will leave this as an exercise for you to complete, however if you would like to see my poorly annotated, hacky solution, you can find it here: https://drive.google.com/file/d/0B5pT4hU_yYUWMnBfVTllaHNrMWc/view?usp=sharing

Conclusion

I hope you enjoyed this tutorial and it inspired you to get into crackmes more :) I appologise if it was overly detailed in places but I wanted to make as many people could follow along as possible. Let me know if you have any comments or feedback!

-tekwizz123







Saturday, February 20, 2016

An Update and Some Tips and Tricks I Picked Up

Intro

Quick note before I start this, but I am writing this at 12:36 am my time so please excuse any spelling mistakes etc you may find :)

Some Lessons

Its been a long time since I've last done a post on this blog and I think enough has changed in my life that I aught to discuss some of the things that have occured. For those of you not already aware, since I last updated by blog I finished my studies as a Junior Security Consultant at NCC Group and have now graduated to a full time security consultant. As a result of this I've been busy bouncing back and forth between various jobs for several of NCC Group's clients, an experience that has proven to be both interesting and unexpected in a number of different ways.

In particular, one of the things that suprised me the most was how different everyone's experience is when it comes to performing professional pentration tests. Whilst my internship at MWR Infosecurity exposed me to this somewhat, its become much more apparent over the last few months that there are a wide range of skillsets within the infosec industry and that it really is quite impossible to master every single one of them, or even truely gain indepth knowledge of a few of them, without actual experience working with those products. There is simply too much to learn within a single field of security. As thus I've found that many people tend to choose one main area of study that they want to truely master and then another 2 or 3 additional areas that they try to remain knowledgeable about. This is just my experience though an in no way should act as a delimter to stop someone from trying to learn as many feilds as they feel comfortable taking on.

Another thing that I've come to realise more about is the role of certifications these days. Many people I've met have repeatly noted that they are not comfortable with the idea of certifications within the security community, and having done some jobs for NCC Group, I can honestly say that I understand why this is the case. Whilst I have done several security certifications such as OSCP and OSCE in the past, and they have no doubt help build the basics in my mind, until you are actually put on the job and have to learn things by yourself. Several concepts, tips, and tricks I've only learnt through actually getting hands on with training labs and real world client engagements where one has to come up with solutions to various problems on the fly. While most of you who probably read this blog already know this is the case, you'd be suprise to know that some of the people I've worked with still don't realise the crucial need to self learn or ask for help in these situations. If you don't know how to Google your problem, your going to have a bad time and your just wasting your time, your clients time, and the companies time.

Finally, I  found it really odd how many pentesters I've met from various companies whilst working who don't know how to program. Understandably, some pentesters may feel that they don't need to learn programming as most of their job consists of running tools that others have programmed and then interpreting the output to report to the client. Unfortunetly, without a proper understanding of programming, one will not understand the true underlying nature of a lot of security issues that he/she reports, which will hamper one's ability to explain the true impact of a bug on the client's systems.

Future Plans - Defcon, Exploit Development Stuff, Misfortune Cookie, etc

With all this aside, I wanted to say that this year I will be planning to attend Defcon 24 this year and will be self funding a trip down to Las Vegas to come see all you guys in the USA :) If your in the area or planning to attend, feel free to give me a shout; it would be great to meet up with all of you!

Some of you guys have also been asking why I haven't been updating the blog with any stuff reguarding exploit development. The thing is that while I am still working on exploit development from time to time (its not so easy doing it inbetween jobs), a lot of it is still either a work in progress, or covered by company NDA agreements, so I can't really discuss a lot of it. That being said, if you are interested in some of the work that I have done recently, feel free to take a look at https://www.nccgroup.trust/globalassets/our-research/uk/whitepapers/2015/10/porting-the-misfortune-cookie-exploit-whitepaperpdf/ for one of my whitepapers I did on porting the Misfortune Cookie exploit to support more target routers. Unfortunetly due to the company's policy on exploits, I am prohibited from releasing any of these exploits publicly or too many screenshots on the whole process, however the whitepaper tries to provide an overview of the process and the problems that I encountered as best as I could.

I've actually had a lot of thoughts about how I plan to continue to develop my skills in the future. One of my concerns is the combination of pentesting and exploit development burning me out in the long haul, however at the same time I realise theres a certain point where this thought is just dragging me down and preventing me from doing anything useful. To that extent I am planning to try go through The C Programming Language 2nd Edition by Brian W. Kernighan and the late Dennis M.Ritche to recover C programming basics and ensure that I don't have any gaps in my knowledge as I feel there are some areas that might need reinforcing. I'm hoping to then go through The Shellcoder's Handbook Second Edition as I really need to go through some of the basics in that book such as heap overflows, fuzzing and format string bugs.

Conclusion

With all that being said, I'm very happy to be working with NCC Group at the moment and I hope to try and update this blog some more in the foreseeable future if it is at all possible, however the main thing I wanted to get across here is that because of NDA's and work life, I may end up posting less on this blog than normal. Hopefully though, I will be publishing some whitepapers and technical articles though NCC Group and I'll likely be notifying you guys of any updates on that side of things through my blog or Twitter.

Until the next update, keep learning guys :)

- Grant

Wednesday, November 11, 2015

Some Observations On Duo Security's "WoW64 and So Can You" Paper

So presently I haven't been posting a lot due to ongoing work at NCC Group but I stumbled across something interesting I thought would be good for a quick post whilst reading Duo Security's "WoW64 and So Can You" paper. In the paper, they describe how many of EMET's protections, whilst properly applied in pure 32 and 64 bit contexts (with the limitation that a few ROP mitigations don't work so well on 64 bit programs if I recall correctly, though this may have been fixed since then), are not applied well or even at all within WoW64 contexts. As described very nicely within their paper (which I am just briefly sumarizing here for simplicity and convience's sake) WoW64 is essentially a compatability layer for 64 bit operating systems to run pure 32 bit applications within their 64 bit environment.

The real problem for EMET is that the way this is implemented is essentially to have two contexts running for the application at the same time, one to support 32 bit (aka protected mode) operations and one to support 64 bit (aka long mode) operations. When I say two contexts I really do mean two contexts here. There are sepearte TEBs (thread execution block, which handles the threads for the program), PEBs (process execution block, which contains data structures which apply for the entire process), and a number of different DLL imports and redirects which all help to ensure that the application is able to run on the 64 bit operating system.

The problem that occurs here when one considers that an application can switch between 32 bit and 64 bit modes during execution with a single instruction. At this point it becomes very hard for EMET to properly enforce it's protections as whilst it may intially implement it's function hooks, hardware breakpoints and other protection mechanisms under the assumption that the application is running as 32 bit code, as soon as the application switches to 64 bit mode, these protections are essentially rendered useless as now different code, libraries, and execution environments are being used which are no longer subject to the protections implemented on the 32 bit code. To add further complications to the matter, even if these protections where to somehow be brought over from the 32 bit code, one has to reimplement them in 64 bit code to match the new execution environment, otherwise they would not function correctly.

What I found particularly interesting was in their"Address Space Layout Section" where they described how they attempted to find where the 64 bit copy of ntdll.dll that was loaded into the WoW64 process is located so they can start calling functions from it within their shellcode. In particular I found particular interest in their second point, which I'll quote here:
The order in which modules are loaded is reliable, resulting in predictable module alignment presuming no change in module size (in practice, we have found this alignment to be reliable across a variety of patch levels).(https://www.duosecurity.com/static/pdf/WoW64-Bypassing-EMET.pdf)
You may recall my post An Theoretical Approach to Getting Around EMET's EAF Protection in which I described a way to potentially get around EMET's EAF protection in a similar manner. By looking up a function with the export table which is located in the same DLL as the function we wish to call, we were able to obtain a base address from which to start our calculations. From there we abused the fact that functions within a DLL tend to be located at set offsets from one another to find the location of the function we wished to call by taking the address of the function that we had located from the export table and adding or subtracing the offset to get the address where our desired function had been loaded in memory. I did also note after some comments from Reddit that the exact offset may change across patch levels due to the fact that the size of different functions within the DLLs may change, thus affecting the exact size of the offsets between functions.

In a similar manner, Duo Security managed to abuse the fact that the order in which the DLL's are loaded into a WoW64 process on Windows 7 are always located at set offsets from one another, assuming no change in module size. That sounds rather familar right? They even mention how changes in module (aka DLL) size and patch versions will mess up their technique. So it seems to be rather similar to the technique that I ended up using in my research paper.

I just wanted to point this out in case anyone was interested and also to bring up another point to think about when considering EMET bypasses, namely that whilst ASLR does have a large impact by preventing an attacker from learning the location where modules are loaded in memory, there are still ways, in the right environment, by which one can figure out their location without resorting to memory leaks or other exploits.

Will be interesting to see if anyone takes Duo Security's research and applies it to some real world public exploits as I would be interested to see how such techniques handle themselves when confronted with different vulnerable targets and exploit scenarios.

Until next time,
Grant (aka @tekwizz123)

Wednesday, July 1, 2015

Final Year Dissertation Paper Release: An Evaluation of the Effectiveness of EMET 5.1

Update (July 26th, 2015 4:00pm): So looks like I've finally got an answer reguarding this issue. A representative from the Export Control Organisation responded back saying that, as some of you have pointed out, by releasing my research publicly I would not be subject to the terms of the arrangement due to the public domain exception clause. Futhermore, they also do not consider exploits or intrustion software itself to be controlled by the new 'intrusion software' related controls for export from the UK or EU. Therefore it looks like I should be clear to release the full report to the public. I have attached a screenshot of the email below as proof of evidence and so you can read the details and full and make your own interpretation in case I have misread anything:



Update (July 20th, 2015 7:20 pm): Sorry for the delay reguarding this issue. I have recieved another update from the Department for Buisness, Innovation and Skills reguarding my questions. They have apparently decided to forward my question on to the Export Control Organisation who deal with export licenses and any conflict with the Wassenaar Arrangement. The email was sent on July 17th, as you can see below. I will await a response.

 
Update (July 15th, 2015 2:04 pm): So I have recieved an update from the HMRC government reguarding what they think about this issue as well as a minor update from my university. Starting with the university (since that is simpler), they are still working on getting things organised but are looking to try push the issue past the ethics board after I have stated my case as to why I believe the exploits, and subsequentally the whole research, should be published in full.

You can see the email response that I got from the uni below. For reference Julie Horton is the head of all of the final year dissertation projects at Northumbria University and also acts as a mediator of sorts to ensure that projects fall within the university's ethical guidelines. Martin Wonders, who you may see cc in the email above this one, was my project supervisor:


With that being said and done, I have recieved a final answer from HMRC. Unfortunetly despite my persistance reguarding the matter and repeated questioning of whether or not the paper was within the export restrictions guidelines, all I got as an answer was "look at the export guidelines". Here is the full chat log that I had with HMRC for reference:







In summary, the gist of the email is that the HMRC (who are one of two bodies responsible for enforcing export controls over here) referred me to the Department for Buisness, Innovation and Skills reguarding my original export question, at which point they have then repeatively told me that I need to align my research with reguards to the export control lists without stating whether or not my research actually falls within the tolerances of the export control lists or not.

Therefore at the moment, until I get a response back from my uni I can't really do anything. I've heard a lot of people state that the research should be ok to release publicly and provided the export controls in the UK are indeed in line with what I think they are it shouldn't be an issue but still working on getting the university side of things sorted out. Hopefully this will all become clear sometime soon.

Update (July 5th, 2015 23:47 pm): In light of the attention this post and the associated paper has been getting I would like to discuss my current plan of action. Many of you have said that I should just release the code publicly and get it over and done with. Whilst I would like to do this, I do not believe this to be the best of course of action. 

Instead I have decided to talk to my supervisor and the uni's ethics board again to see what can be done about releasing the code. As far as I am aware (this is from my main project supervisor) it should be possible to get the uni's ethics board to review and possibly change their decision to allow the code to be released but obviously this will take time.

The other thing that I have done is contacted the HMRC, one of the enforcing boards of the Wassenaar Arrangement here in the UK, to get their official opinion on this situation. I believe this is necessary to prevent such situations from happening in the future and at least get the UK government's opinion on such matters, which will hopefully help others who wish to release similar research in the future.

Please be patient with me whilst I continue with this process. I know you guys think I'm being naive/silly/w.e but at the end of the day this is my decision and this is what I believe is the best course of action for all involved.


This post has been in the works for a long time, however I wasn't able to release it until my official results came out due to concern about collusion which could have resulted in my university changing the results of my grade. However now that the grades have been published and results are final, I can share with you guys something I have been meaning to share for quite a while: my final year dissertation paper.

My paper covers three separate exploits that I converted to try bypass EMET 5.1's protections as best I could and the techniques that I used to do so as well as how successful EMET 5.1 was at preventing me from exploiting the vulnerable programs.

Before proceeding, please note a couple of very important points:

Update (July 26, 2015): Paper has now been released in full.
  • I am aware there are a few conceptual issues the approach I used for this paper. In particular, the technique that I used to bypass EAF and locate the functions needed to create the final exploit does not work consistently across different patch versions of the same operating system (aka a clean, unpatched version of Windows 7 will need different offsets than a fully patched version of Windows 7). Whilst further research did find that only a very limited number of core kernel updates affect this issue, it still is a huge limitation and is something that I would look to fix if I had more time in the future.
  • There may still be spelling or grammatical issues within this document, for which I apologise in advance. I have looked through the paper several times so most issues should be resolved but please let me know if you find anything.
  • There are a couple of sections within the paper that were purely for the uni. Please feel free to skip these as they are not relevant to the paper's content :)

With all that being said, please do enjoy the paper :) I hope you manage to learn something from it.

Download (full, uncensored version): https://drive.google.com/file/d/0B5pT4hU_yYUWLXVZVTlBa05La1E/view?usp=sharing

Download (old censored version):  https://drive.google.com/file/d/0B5pT4hU_yYUWcUtsUWxxcFJjOVU/view?usp=sharing

Friday, June 12, 2015

Nebula Exploit Exercise Level 00 Walkthrough

Intro

So this is more of a reminder post to myself to track my progress through this thing, but I thought I might as well do a post seeing as there are already about 6 other solutions out there and the authors don't seem to mind walkthroughs too much.

That being said, this is level 00. If your getting stuck on this, you should seriously try harder before you look at the solution. If you want to check your work however and think you have the solution, feel free to read on :)

The Problem

For Nebula's level 00 exercise, we are tasked with finding a setuid program that will run as the flag00 user. We are also given the hint that reading the manual page for the find command may help us find where this file is located.

So my first approach to this was to look up the manual page for the find command. However the manual page for the find command contains many different options and switches. Lets try grep out anything mentioning setuid or something along those lines shall we?

Solving the Problem

First we log in with the username level00 and the password level00. Following this we issue the following command:
man find | grep -i suid
      \( -perm -4000 -fprintf /root/suid.txt %#m %u %p\n \) , \
       into /root/suid.txt and large files into /root/big.txt. 
We see that we can could run find / -perm -4000 to find all of the files with the setuid bit set from the root directory downwards. But why is this the case? If we look up setuid within Wikipedia we get the following information:
The setuid and setgid bits are normally set with the command chmod by setting the high-order octal digit to 4 for setuid or 2 for setgid. "chmod 6711 file" will set both the setuid and setgid bits (2+4=6) (Wikipedia, 2015, June 12 2015, https://en.wikipedia.org/wiki/Setuid)
Thus from this we can see that within the UNIX privilege management system, the first number (the 6 in chmod 6711) denotes if the file has setuid or setgid permissions or not. Thus by searching for files via find / -perm -4000 we are effectively searching for all of the files which have the setuid bit set. However this could return quite a few files, so lets pipe the output to a file and then cat the result.
level00@nebula:~$ find / -perm -4000 > /tmp/results.txt
level00@nebula:~$ cat /tmp/results.txt
/bin/.../flag00
/bin/fusermount
/bin/mount
/bin/ping
/bin/ping6
/bin/su
/bin/umount
/sbin/mount.ecryptfs_private
/usr/bin/at
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/gpasswd
Ah, there we go :) We see that there is a file /bin/.../flag00 which seems to hold the suid flag that we need to complete this level. Lets check:
level00@nebula:~$ ls -alh /bin/.../flag00
-rwsr-x--- 1 flag00 level00 7.2K 2011-11-20 21:22 /bin/.../flag00
That looks like the one :) And if we execute it and then run getflag, we will see we have completed the challenge:
level00@nebula:~$ /bin/.../flag00
Congrats, now run getflag to get your flag!
flag00@nebula:~$ getflag
You have successfully executed getflag on a target account

Thursday, June 4, 2015

BSides London 2015 In Review

Hey guys, thought I would give a quick update as to some of the stuff that is going on in my life. Yesterday I went down to BSides London for another yearly event of meetups and talks. The event was great and I bumped into a whole bunch of people I hadn't seen in quite a while including some mates of mine from uni, and some pentester mates (@TheXero, @Zy0d0x, @n0x00, Duncan, and some other mates)

The keynote presentation was by Wendy Nather and it touched on the importance of privilege and usability within digital security and how assumptions about how users will interact with a system could result in client frustration and the creation of insecure systems.

The next presentation that I attended was @__Freakyclown__'s "How I Rob Banks". This excellent talk covered some of the security failings __Freakyclown__ had encountered when testing the security of modern banks. In particular it drove home the point that even if the company purchases the most top notch digital security gear, that does not necessarily mean that they spent as much money on their physical security. To highlight the simplicity of some of these issues he walked through some examples he had encountered in past engagements and how he managed to bypass the security mechanisms in place in each of the scenarios.

One particularly interesting example demonstrated was the bypassing of a invisible fence which used microwave waves to detect intruders. The only problem is that microwaves don't pass through all surfaces. Because of this, he was able to bypass their defences by crawling on the ground and using a group of low shrubs (which were blocking microwaves from passing through) to get past their initial external security.

Following __FreakyClown__'s talk, I decided to do a little bit of HallCon and grab some of the free lunch that was being offered. At this point I happened to bump into several people that I hadn't seen in quite a while and spent some time catching up with them. A noticeable difference from last year's BSidesLondon was that the conference venue seemed to be much more organised this year with a larger focus on HallCon, as evidenced by the chairs and tables in the vendor room as well as the ample free space throughout the conference.

Having completed caught up with people, I then decided to go to the workshop "Dradis Framework 3.0 - We Are Back!". To be completely honest I felt this workshop was a bit of a let down. Although Daniel Martin was an excellent teacher and was happy to help out, the Dradis 3.0 framework itself was found to need a lot of work. The reason for this was although the ready to go packages came with all of the prerequisites needed to run Dradis 3.0, it did not come with any plugins to import results from other tools. Futuremore, it was not currently possible to add additional plugins to this readily deployable version of Dradis without considerable time and effort.

Speaking with Daniel Martin (@etdsoft), he revealed that the original plan for these prebuilt packages was to strip all the plugins out and allow people to install them as they desire, however he has found that this doesn't work at the moment without a long and very complicated install process. As thus, he is planning to release a future version with all of the plugins installed from the start so people can remove the plugins as they desire. Hopefully this will be fixed in future releases, as I have heard many good things about the tool and seen some very interesting things that it is capable of doing.

The last workshop that I went to was Ruben Boonen (@FuzzySec) and Francesco Mifsud (@GradiusX)'s "Windows Privilege Escalation". The room was pretty full for this one, which was to be expected given the amount of interest it had generated :) The workshop covered some common issues within Windows services and applications that would allow one to escalate their privileges on Windows machines. The class went really fast, however thankfully they added notes into the material that they released in case anyone fell behind so it was pretty easy to catch up.

I learned a lot from this one from simply just going through the slides and materials and trying stuff out so it was well worth it. That being said however I think I need a lot more practice as there were quite a few commands that I either had never used before (such as findstr) or with which I was only vaguely familiar. Overall this had to be one of the better talks that I attended and I hope Ruben and Francesco decide to continue it in the future as I think it helped quite a lot of people out.

At this point the day was pretty much wrapped up and the only thing left was the closing remarks which consisted of some quick comments and some raffle draws/prize handouts.

Overall the event was thoroughly enjoyable and I really hope to go again. I can honestly say this was one of the few events where I didn't find a single major issue with the whole event, which was a rather pleasant surprise. I hope I can attend next year and that BSidesLondon will continue offering amazing talks and events.