yashsingh1/xdaforums huggingface dataset:
[Windows RT Development and Hacking] clrokr:
I am very sorry guys, but g_CiEnabled is not in the ARM kernel. Every section where it would have been checked is now just the "1" part of the if condition. There is however g_CiOptions in ci.dll, so we could maybe load drivers.

We can change data using this bug in some situations, HOWEVER we can NOT patch kernel code. Only data. We need to find a check that uses a data page.

Or we find out how to set g_CiOptions to 0 which enables test signing (not sure if we can do that after boot is complete). To do that we need to:

1. Figure out CI.DLL base address.

2. Set g_CiOptions from whatever it is now (disassembly say it's 0x00000006) to zero using the vulnerability in win32k!NtUserSetInformationThread. This could work because the dword that comes after it is g_EtwEventHandle which is probably not zero at runtime.
[Windows RT Development and Hacking] netham45:
1: kd> dq ci
8bcbe000 00000003`00905a4d 0000ffff`00000004

1: kd> dq ci!g_CiOptions
8bccd984 946e90b0`00000026 00000000`ffffffff
8bccd994 00000000`00000000 00000000`00000000
8bccd9a4 00000000`00000000 00000000`00000000
8bccd9b4 00000000`00000000 00000000`00000000
8bccd9c4 00000000`00000000 00000000`00000000
8bccd9d4 00000000`00000000 00000000`00000000
8bccd9e4 00000000`00000000 00000000`00000000
8bccd9f4 00000000`00000000 00000000`00000000

Edit: Just to note, I'm using a memory.dmp I got by forcing a BSoD (Killed CSRSS inside the performance monitor) with windbg on my desktop.
[Windows RT Development and Hacking] clrokr:
Nice find. We could also try setting g_CiDeveloperMode to 0xffffffff. If it is zero now maybe we need only one iteration. I will analyze a crash dump, that is a very very good idea and i don't know why i didn't think of this. Too focused on static analysis i guess.
[Windows RT Development and Hacking] netham45:
Here's the dq for that one:

1: kd> dq ci!g_CiDeveloperMode
8bccd858 00000001`00000000 00000001`00000000
8bccd868 8bcc10ac`00140000 00000000`00000000
8bccd878 a5dd6ada`00000ad5 a5dd6000`00000ada
8bccd888 00000002`00000000 00000000`00000000
8bccd898 00000000`00000000 8689a620`83648000
8bccd8a8 00000000`00000000 00000000`00000000
8bccd8b8 00000000`00000000 00000000`00000000
8bccd8c8 00000000`00000000 00000000`00000000
[Windows RT Development and Hacking] clrokr:
That's interesting, here's mine.

0: kd> dq ci!g_CiDeveloperMode
8bcd6858 00000000`00000000 00000002`00000000
8bcd6868 8bcca0ac`00140000 00000000`00000000
8bcd6878 958dcada`00000ad5 958dc000`00000ada
8bcd6888 00000002`00000000 00000000`00000000
...
[Windows RT Development and Hacking] netham45:
Perhaps it's referencing the developer certificates for metro apps? Do you have a developer license installed (I do, but I believe it was marked as invalid due to me messing with the system clock)?
[Windows RT Development and Hacking] clrokr:
It seems to be a bit mask. For example, if the third bit is set, it completely overrides the results of CipGetAcceptedRootKeys and changes the behavior of CipMinCryptToSigningLevel.

The first bit is used in CiValidateImageHeader to ignore a policy failure if it is set. An event log is created.
[Windows RT Development and Hacking] peterdn:
Sorry, I'm trying to follow along with you guys, but my lack of knowledge of the tools is showing.

How are you connecting to the Surface with windbg in order to kill CSRSS, or am I misunderstanding this?

Where did you manage to find the symbols in the end?
[Windows RT Development and Hacking] clrokr:
On his device, he killed the process in resource monitor, you can find it under "administrative tools". This triggers a "bugcheck" aka bluescreen. You can copy the file C:\Windows\MEMORY.DMP to another machine that can run WinDbg. There you can load the file and debug the situation.

The symbols are on the MSFT symbol server at http://msdl.microsoft.com/download/symbols, you can google instructions on this.

In the meantime, if you encounter any unrelated bluescreens, please do share the memory dumps with someone on this thread. It may help.
[Windows RT Development and Hacking] peterdn:
Fantastic, thanks
[Windows RT Development and Hacking] clrokr:
Found a place in winsrv.dll!AutoRotationRequestThread that calls win32k!NtUserSetInformationThread. Let's see what I can do about this one.
[Windows RT Development and Hacking] netham45:
Things are starting to get exciting. Keep us posted, and let me know if you need me to look at anything.
[Windows RT Development and Hacking] clrokr:
I am reversing NtUserSetInformationThread to find the parameters needed to exploit the vulnerability. Sadly the article is missing some important details (it's a good thing though, with script kiddies and all).

You can use VS2012 to set a breakpoint at winsrv!AutoRotationRequestThread and step through it to find the system call to NtUserSetInformationThread. I can't make sense of the parameters right now, it doesn't seem to add up. The THREADINFOCLASS enum seems to have changed with Windows RT.

We got this!
[Windows RT Development and Hacking] netham45:
Somehow trashed the OS on my tablet, it's reinstalling right now. In the meantime, here's what I found in the SDK for that class:

winternl.h

typedef enum _THREADINFOCLASS {
ThreadIsIoPending = 16
} THREADINFOCLASS;
[Windows RT Development and Hacking] clrokr:
I need the enumeration for integer value 7. Every source I can find points to the value "ThreadEnableAlignmentFaultFixup". Here is the documentation from MSDN:

NTSTATUS ZwSetInformationThread(
_In_ HANDLE ThreadHandle,
_In_ THREADINFOCLASS ThreadInformationClass,
_In_ PVOID ThreadInformation,
_In_ ULONG ThreadInformationLength
);

In winsvr!AutoRotationRequestThread this method is called with the parameters:

HANDLE ThreadHandle in register R0: 0xFFFFFFFE aka INVALID_HANDLE
THREADINFOCLASS ThreadInformationClass in register R1: 0x00000007 aka ThreadEnableAlignmentFaultFixup
PVOID ThreadInformation in register R2: 0x02F0F9A0, contents:
775265b5 00000000 00000000
ULONG ThreadInformationLength in register R3: 0x0000000C (12)

Now the problem is that ThreadEnableAlignmentFaultFixup suggests a ThreadInformationLength of 4 and a BOOL value at the pointer. The function call returns SUCCESS however.

Needs more digging, I'm on it.
[Windows RT Development and Hacking] peterdn:
The point at which NtUserSetInformationThread is called from winsrv!AutoRotationRequestThread looks like (with my attempt at annotating the parameters; it appears to be fit with the official ARM calling convention):

4C68330C: 230C movs r3,#0xC 'ULONG ThreadInformationLength
4C68330E: AA0A add r2,sp,#0x28 'PVOID ThreadInformation
4C683310: 2107 movs r1,#7 'THREADINFOCLASS ThreadInformationClass
4C683312: F06F 0001 mvn r0,#1 'HANDLE ThreadHandle
4C683316: F001 FF0D bl NtUserSetInformationThread

Which seems to be either inconsistent with the documentation (implies only ThreadPriority and ThreadBasePriority are valid values) or the x86/x64 THREADINFOCLASS. From ntddk.h:

typedef enum _THREADINFOCLASS {
...,
ThreadPriority = 2,
ThreadBasePriority = 3,
...,
ThreadEnableAlignmentFaultFixup = 7,
...
}

From what I can work out, this value is only checked once in NtUserSetInformationThread (where it is compared to 1). It then passes to xxxSetInformationThread where I get a bit lost, though I think it ends up being checked in a switch().
[Windows RT Development and Hacking] clrokr:
Yes, there is a jump table. We need ThreadQuerySetWin32StartAddress (9) to . I found a place that uses this command in winsrv.dll!TerminalServerRequestThread that gets executed every time a volume button is pressed. But they still use invalid handles with success. I'm going to sleep now, but it's looking good.
[Windows RT Development and Hacking] peterdn:
Awesome, I think I see what's going on now.

Also, could I get the base address of winsrv.dll if possible? For some reason windbg refuses to find the module in any of my crash dumps:

2: kd> dq winsrv
Couldn't resolve error at 'winsrv'
[Windows RT Development and Hacking] clrokr:
You can't see it because you killed csrss.
[Windows RT Development and Hacking] peterdn:
I also forced a full memory dump by killing wininit.exe with no joy.

EDIT: never mind, I forgot about the VS2012 debugger modules window
[Windows RT Development and Hacking] clrokr:
I think killing wininit kills the subsystem as well. But you can find the address out at runtime using VS.
[Windows RT Development and Hacking] netham45:
D'oh!

Oh well, here it is:

0x75310000

On an unrelated note, I can't seem to force a BSoD using the ctrl+scroll+scroll trick
[Windows RT Development and Hacking] peterdn:
Hmmm, so attempting to get it to decrement one of the words located near ci!g_CiDeveloperMode (at 0x8bce9868) results in an ATTEMPTED_WRITE_TO_READONLY_MEMORY (CI.dll).

EDIT2 OK, that location doesn't seem to be fixed between reboots so that explains it.... we need some way of getting base address of CI.dll without killing the system?

EDIT windbg analyze

ATTEMPTED_WRITE_TO_READONLY_MEMORY (be)
An attempt was made to write to readonly memory. The guilty driver is on the
stack trace (and is typically the current instruction pointer).
When possible, the guilty driver's name (Unicode string) is printed on
the bugcheck screen and saved in KiBugCheckDriver.
Arguments:
Arg1: 8bce9868, Virtual address for the attempted write.
Arg2: 860cf212, PTE contents.
Arg3: 8fbbf9f8, (reserved)
Arg4: 0000000b, (reserved)

Debugging Details:
------------------

DEFAULT_BUCKET_ID: WIN8_DRIVER_FAULT

BUGCHECK_STR: 0xBE

PROCESS_NAME: csrss.exe

CURRENT_IRQL: 0

TRAP_FRAME: 8fbbf9f8 -- (.trap 0x8fbbf9f8)
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
r0=8bce9880 r1=0000003e r2=0000014b r3=00000000 r4=00000000 r5=00000000
r6=00000000 r7=00000000 r8=00000000 r9=00000000 r10=00000000 r11=8fbbfbb0
r12=b42d13a5 sp=8fbbfb98 lr=830d2657 pc=8346efe0 psr=20000073 --C-- Thumb
nt!ObfDereferenceObject+0x28:
8346efe0 e8454300 strex r3,r4,[r5] 00000000=????????
Resetting default scope

LAST_CONTROL_TRANSFER: from 83576850 to 83576228

STACK_TEXT:
8fbbf670 83576850 : 0000000b 8fbbf6e0 88203900 83575ee5 : nt!KeBugCheck2+0xfc
8fbbf928 835a43c0 : 0000000b 00000000 8fbbf9f8 860cf212 : nt!KeBugCheckEx+0x14
8fbbf940 8348b7da : 0000000b 00000000 00000011 00000008 : nt!_i64tofp_exception_helper+0x18314
8fbbf988 8351b3b2 : 8fbbf9c8 8fbbf9c0 8fbbf9a4 8fbbf998 : nt!MmAccessFault+0x40a
8fbbf9f8 8346efe0 : 8361f530 00000001 8bce9868 8351ace0 : nt!KiCommonMemoryManagementAbort+0xc6
8fbbfb98 830d2656 : 0000014b 8346efb9 8fbbfcbc c0000022 : nt!ObfDereferenceObject+0x28
8fbbfbb8 830d24d4 : 00000003 00000000 00000009 00000009 : win32k!xxxRestoreCsrssThreadDesktop+0x7a
8fbbfbf8 830d22e2 : 8fbbfc1c 00000000 00000000 00000000 : win32k!xxxSetInformationThread+0x94
8fbbfca8 8351bc80 : 00000000 00000000 00000000 00000000 : win32k!NtUserSetInformationThread+0xa6
8fbbfd00 8351ba44 : 00000001 00000008 00000000 00000000 : nt!KiSystemService+0x100
8fbbfd40 74ae513a : 8b970530 00000008 74b71690 74ae365f : nt!KiSWIException+0xe4
0129fc68 74ae3662 : 00000000 00000000 00000000 00000000 : 0x74ae513a
0129fc68 00000000 : 00000000 00000000 00000000 00000000 : 0x74ae3662

STACK_COMMAND: kb

FOLLOWUP_IP:
win32k!xxxRestoreCsrssThreadDesktop+7a
830d2656 6027 str r7,[r4]

SYMBOL_STACK_INDEX: 6

SYMBOL_NAME: win32k!xxxRestoreCsrssThreadDesktop+7a

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: win32k

IMAGE_NAME: win32k.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 5080d243

BUCKET_ID_FUNC_OFFSET: 7a

FAILURE_BUCKET_ID: ARM_0xBE_win32k!xxxRestoreCsrssThreadDesktop

BUCKET_ID: ARM_0xBE_win32k!xxxRestoreCsrssThreadDesktop
[Windows RT Development and Hacking] clrokr:
Great, ASLR is working properly :/ We'll find out. I'm gonna try some more stuff.
[Windows RT Development and Hacking] lilstevie:
This is interesting for future reference, useful or not that this stage (due to unknown sbk being set) at least it is accessible.
[Windows RT Development and Hacking] netham45:
Should be able to disable ALSR with THIS, giving it a try now.

Edit: Still seeing ALSR.

With key set 1: 8c0b5984

With key set 2: 8c0c9984

Without key set: 8bccd984

Something I did notice is that the variable (ci!g_CiOptions) is always 0xF984 from the base image (ALSR key set or not).

I'ma see if it's at the same address in a memory dump as it would be if I loaded it with LoadModule from a Metro app. That'll give us the base image, and g_CiOptions should be at base+0xF984.
[Windows RT Development and Hacking] clrokr:
We don't have to disable ASLR. We have access to the debbuger.
[Windows RT Development and Hacking] peterdn:
Any luck with this? Otherwise we could find some debuggable non-critical process that does a LoadLibrary + GetProcAddress, and force it to load CI.dll?
[Windows RT Development and Hacking] clrokr:
@peterdn: That would probably load CI.dll a second time (only this time in user mode). Worth a try however.

ci!g_CiOptions is a true global variable, so its address (relative to the image base) is fixed by the linker.

I'm skimming through win32k for a read vulnerability to find CI.dll's base address.
[Windows RT Development and Hacking] netham45:
I wasn't able to get ci.dll to load at all in userspace, it just throws MOD_NOT_FOUND, I suspect because the dllmain in ci is erroring out.

Edit: Well, I did something to my tablet, now it's refusing to boot. It's just hanging at the 'Surface' boot splash screen. Going to try letting the battery drain for a while...

Edit 2: Looks like my surface is bricked, I can't get it to do anything. Looks like I'm out of the game until I can get it replaced. Just to note, I don't really have any reason to believe it was related to hacking efforts, though it is always possible.
[Windows RT Development and Hacking] peterdn:
Damn, that sucks. Were you doing anything particularly nefarious on it before it died?

Good luck - I might have a look myself but I suspect it's currently beyond my ability.
[Windows RT Development and Hacking] netham45:
I forced a BSoD to get another crash dump while trying to disable ASLR and it didn't boot after that. It won't boot to recovery either, so I don't think it's the ASLR setting causing the issues.

As I said, I don't have any reason to believe it was related to hacking efforts, though I really have no idea at all what caused it.

Edit: Got a new tablet. The method I was testing to disable ASLR didn't work, so idfk why my old one bricked. On a happier note, MS's support was really nice.
[Windows RT Development and Hacking] smx06:
NB: native internet explorer successfully runs apps from url field

(just enter the full path; runned on x64 far.exe )

Can anybody try the same on Surface RT?

(entering somth like c:\windows\system32\notepad.exe or cmd.exe in url and double confirm the launch)

Also it s very interesting to run hello.world.exe (compiled for arm)

What will happen? maybe it will run with less restrictions!

Thanks
[Windows RT Development and Hacking] sigle:
I tired on Surface RT, but command prompt said,

"The system cannot execute the specified program."

can't launch hello.world...
[Windows RT Development and Hacking] smx06:
Did you compile it for arm? And did it run succesfully from your own native (metro) app ?

I mean running desktop app from native using win32 api from neighbor thread..

What about notepad or cmd.exe (to test metro ie runs apps)

Thanks
[Windows RT Development and Hacking] peterdn:
Good to know. Sounds like this is going to be difficult. Presumably we need some information leak bug that either a) gives us the base address of CI.dll directly; or b) gives us the base address of ntkrnlmp.exe so we can compute ASLR'd base addresses using nt!MiImageBias?
[Windows RT Development and Hacking] SilverHedgehog:
It works just like doubleclicking an .exe from the File Explorer, so it won't work with third party apps.
[Windows RT Development and Hacking] clrokr:
Exactly. There seem to be some ways of getting the kernel base address (which is really all we need because we have the symbols) from user mode. Have a look:

http://alter.org.ua/docs/nt_kernel/procaddr/

I'll have to hand-assemble this code to inject it into a process using VS2012 and find the correct addresses for the library calls and they change every time we reload an image. Still not impossible.
[Windows RT Development and Hacking] netham45:
I haven't had a chance to read through them, but will they run from within the Metro sandbox? I'll give it a look tomorrow, I'm just about to head to bed.
[Windows RT Development and Hacking] clrokr:
I'll find out soon. The most viable method to me seems importing a symbol from ntoskrnl. The .lib for it is in the WDK. I'll import a constant and not a function so I don't get stubs.

We can scan down from this symbol to the PE header, find the loaded modules list using debug information, locate ci.dll and find the address of g_CiOptions.
[Windows RT Development and Hacking] wy328:
just post to say you're awesome! and thanks for your hard works! :highfive:
[Windows RT Development and Hacking] clrokr:
Some bad news, ntoskrnl.lib is available for all platforms except for ARM.

However, dumpin is available for ARM, so I'll find a way. Let's just hope the dynamic linker on ARM plays nice and imports our lib.

NINJA EDIT: Found the base address. Yay! Details coming soon.

NINJA EDIT II: Found CI.DLL base. More Yay.

EDIT 3:

ARM_0x18_OVER_DEREFERENCE_win32k!xxxRestoreCsrssThreadDesktop

Lookin' good.
[Windows RT Development and Hacking] netham45:
Well, hurry up and finish it then. :P

On a more serious note, since you seem to be close to finishing it, what all are you requiring to do this? I'd like to get it made so an app (or possibly a script through the scripting host) could do this all, since it's likely going to lose changes at reboot. What I can see we need is:

Remote Debugger

Ability to communicate with remote debugger, I can't imagine that the network protocol for it is too complex.

.exe that will give us the base address for CI.dll (I'm assuming you packaged it all up in an exe, if not it should be possible)

So we'll need to do this:

Call .exe from metro app to get the base address of ci.dll

Get the address of g_CiOptions (I posted the static offset in one of the previous posts)

Edit csrss in RAM to get it to do the exploitable call (This is what I see being the hardest to automate, seeing as we'll need to get the protocol for the remote debugger. If you get a working PoC I can start working on the debugger protocol, I've done a fair amount of network protocol reversing)

Fire whatever triggers the exploit in csrss (I think you said hitting one of the volume buttons)
[Windows RT Development and Hacking] clrokr:
I think the debugger needs some stuff from the Windows subsystem, so we're going to need a second machine anyway. I'm going to bed now and hopefully I'll have a local solution tomorrow. There also seems to be another layer of protection.

ARM_0x18_CORRUPT_REF_COUNT_win32k

This doesn't exist on Windows for x86 AFAIK. Still no problem :)
[Windows RT Development and Hacking] clrokr:
Okay, so the problem is that the part of ObfDereferenceObject that we use to decrement a dword at an address is implemented like this on ARM (R5 contains our address):

...
LDREX.W R4, [R5] ; Load Register Exclusive
SUBS R4, #1 ; Rd = Op1 - Op2
STREX.W R3, R4, [R5] ; Store Register Exclusive

Here's how the code goes on. R3 contains the result of the STREX.W R3, R4, [R5] instruction which is zero for success.

CMP R3, #0 ; Set cond. codes on Op1 - Op2
BNE loc_try_again ; Branch
CMP R4, #0 ; Set cond. codes on Op1 - Op2
BLE loc_crash_it_now ; Branch
MOV R0, R4 ; Rd = Op2
POP.W {R2-R7,R11,PC} ; Pop registers
...

Problem 1)

It uses LDREX.W which requires 32-bit aligned access. Unaligned access will trigger a MMU fault interrupt which will trigger a bugcheck because Windows thinks it's out of memory.

Problem 2)

It crashes on purpose if the value is low than or equal to zero after this operation.

Approaches

I found some places to possibly disable Code Integrity:

ci!g_CiOptions. Sadly this doesn't work. We can not set it to zero. Every other value doesn't solve the problem.

nt!SeGetImageRequiredSigningLevel uses a non-exported variable. Unfortunately it is byte-sized and not aligned correctly in any way to use with our exploit. It is surrounded by other byte-sized stuff and changing the correctly aligned address causes other bugchecks because the variables belong to the HAL.

nt!SeQuerySecureBootPolicyValue stores a pointer to a data structure it owns. I'm still looking into that.

Findings

On Windows 8 without Secure Boot, SeGetImageRequiredSigningLevel is never called when loading a user process.

Currently looking for more, this post will be my "scratchpad".
[Windows RT Development and Hacking] mamaich:
It is present in ARM WDK. It is not public (yet, as too many people already have it, so soon it would definitely go wild). But anyway you are digging in a wrong direction - you can't import ntoskrnl in your user-mode program, it can be imported only by drivers. And to make a driver - you need to bypass signature checks as we currently can't sign drivers ourselves.

Regarding CI.DLL. This is also a kernel-mode DLL, so finding its base address would give you nothing as you need to patch kernel memory. And if you can patch it - you already can do anything.

As I still don't own an RT device (waiting for a quadcore snapdragon), I'm only looking into the dump I have. And in the dump I see that lots of EXE files in system32 directory don't have digital signatures at all. So I'd recommend to look in that direction. But you'll probably need to somehow update the S256H value in registry.
[Windows RT Development and Hacking] clrokr:
I already solved this problem as you can see from the posts above.

We have a write-only vulnerability. Tell me how that enables me to find out anything. Anyway, problem is already solved.

What device is the dump from? It may be a developer's kit or something like that. Also, some of the signatures are not in the files themselves but in "catalogs".
[Windows RT Development and Hacking] UBNAS81:
I have absolutely no idea what you guys are doing with this code (totally another language to me) - but if your doing what I think you are - getting desktop Apps to RT - If you figure it out, and get some sort of emulator, or something along those lines...you will be in line to make some $$.......I know i'd pay to use it, thats for sure. The real ? is - will MS allow it, and if not, can you figure out a way to work it without MS approval (maybe similar to Root / Jailbreak on Android and IOS respectively.

It looks like your making progress - I check this thread every week or so to see if any major breakthroughs talked about in English (lol)

Thanks for the hard work, i think i speak for all early adopters!
[Windows RT Development and Hacking] clrokr:
There's no emulation needed, all the functionality is there. It's really just a matter of time until someone unlocks it. In fact, if your native apps works with almost no privileges you can run it right now.