GithubHelp home page GithubHelp logo

35c3_modern_windows_userspace_exploitation's Introduction

35C3 Modern Windows Userspace Exploitation

At 35C3 I gave a talk named “Modern Windows Userspace Exploitation”, that covered the main exploit mitigations in Windows. The point of the talk was to introduce and evaluate the different mitigations that impact memory safety issues, and examine what kind of primitives an exploit developer would need in order to bypass them (since it’s quite a non-trivial process). Since I feel that the best way in order to do this is by example, I used a CTF challenge as a target, and exploited it on Windows 7, Windows 10 TH1 and Windows 10 RS5. The exploits target the great “Winworld” CTF challenge, from Insomnihack CTF Teaser 2017, written by @awe (thanks for writing this!). For a full explanation of what’s going on in this repo, I recommend watching the talk. The exploits in this repo are based on awe's repo, that had a full exploit for this challenge. There are a couple of key differences between them, though: first, I tried to aim for the simplest exploit for every one of the versions and mitigations I covered in the presentation. The original challenge ran on Windows 10 pre build 16179, compiled with CFG and without ACG, CIG and Child Process Restriction. Second, I used a completely different technique to leak the stack address. While I explained how I gained arbitrary RW and jump primitives in the talk, I didn’t explain this trick, so I will explain it below.

In his exploit, @awe chose to scan the heap memory, hoping to find random stack pointers there. It is a well known technique (for example, see @j00ru’s post). It works great for CTFs but it does reduce the reliably of the exploit: in my experiments it worked once every ~X times . To improve reliability, I used a more deterministic technique, by calling ntdll!RtlCaptureContext. The function looks like this:

I’m not the first one to use this function to leak the stack (here, for instance). It gets as its first argument a pointer to a ContextRecord structure and writes there the current value of all registers. One of them is rsp, so by calling this function and reading the value it wrote, the exploit can retrieve the stack address.

For a full explanation of the arbitrary RW and jump primitives, see talk video, slides, and @awe mentioned them in his writeup as well.

One problem that causes instability of the exploits is that calling ntdll!RtlCaptureContext on a Person object actually corrupts the heap metadata, because sizeof(Person) < sizeof(ContextRecord). When the exploit changes the onEncounter function pointer, it simply sprays more std::strings of commandlines. This “spraying” is dangerous, since commandline is freed immediately after. Put simply, the exploit allocates and frees many chunks, and due to the randomization in the LFH, it writes data on many different chunks in the userblocks. That’s great for setting the uninitialized values in the freed Person instance, but with some low probability, it might hit a corrupted chunk and crash on free(). The solution for that is to leak the address of some other person instance in memory, and use my arbitrary write to corrupt his onEncounter function pointer to points to ucrtbase!gets, and use it as generic reader/writer. And then we can read the stack pointer relatively to our corrupted person (which we have), with our arbitrary read, without spraying any other std::string. Note that the offsets in the exploits depend on the specific builds I used. Other builds may require different offsets relative to ntdll.dll and ucrtbase.dll base.

35c3_modern_windows_userspace_exploitation's People

Contributors

saaramar avatar saaramar-msft avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.