• Introducing XDA Computing: Discussion zones for Hardware, Software, and more!    Check it out!
  • Fill out your device list and let everyone know which phones you have!    Edit Your Device Inventory

It has begun - WinRTs first taste of freedom

Search This thread

cx1

Senior Member
Aug 14, 2007
211
46
http://surfsec.wordpress.com/2013/01/06/circumventing-windows-rts-code-integrity-mechanism/


Circumventing Windows RT’s Code Integrity Mechanism
January 6, 201355

clrokr (@clrokr) – 6. Jan 2013
It’s taken longer than expected but it has finally happened: unsigned desktop applications run on Windows RT. Ironically, a vulnerability in the Windows kernel that has existed for some time and got ported to ARM just like the rest of Windows made this possible. MSFT’s artificial incompatibility does not work because Windows RT is not in any way reduced in functionality. It’s a clean port, and a good one. But deep in the kernel, in a hashed and signed data section protected by UEFI’s Secure Boot, lies a byte that represents the minimum signing level.
Finding the right spot

The minimum signing level determines how good an executable’s signature is on a scale like this: Unsigned(0), Authenticode(4), Microsoft(8), Windows(12). The default value on x86 machines is of course 0 because you can run anything you like on your computer. On ARM machines, it defaults to 8.
That means that even if you sign your apps using your Authenticode certificate, the Surface or any other Windows RT device (at this moment) will not run them. This is not a user setting, but a hardcoded global value in the kernel itself. It cannot be changed permanently on devices with UEFI’s Secure Boot enabled. It can, however, be changed in memory.
Finding this byte in the kernel takes a while, there is no exported symbol for it and not even in the symbol database at MSFT. I found it using WinDbg and a machine running Windows 8 Pro, creating processes and watching how the system behaves when the signature checks happen all the way through CI.dll and back. Because Windows 8 and Windows RT are so similar, locating it in the ARM kernel was not hard:

SeGetImageRequiredSigningLevel+0x18
LDR R3, =0x59FFA6 This is our byte, 0x19FFA6 at 0x400000 image base
LDRB R3, [R3]
CMP R3, #4
BHI loc_HighSigReq
B.W loc_LowSigReq

There are many more places where you can find this byte accessed, but none of them have an exported symbol.
Prerequisites

A while ago I read an article about how the Windows kernel assumes that data passed by certain processes is always well-formed [1]. This vulnerability exists in Windows RT, but exploitation is a bit harder than on Windows 8 because unsigned binaries can’t be run in the first place (and store apps don’t have the security context you need to attach to other processes). But Microsoft decided to provide something very important [2] that made this whole endeavour a lot easier. This remote debugger, when run as Administrator, can attach to the user’s CSRSS process and manipulate its memory.
CSRSS contains a lot of calls to the vulnerable NtUserSetInformationThread function, including some that use the right parameters to exploit it. This is one of them (from winsrv.dll):

TerminalServerRequestThread+0x230
MOVS R3, #0xC
ADD R2, SP, #0x58
MOVS R1, #9
MOV R0, 0xFFFFFFFE
BL NtUserSetInformationThread

A CSRSS thread executes this code. Using a breakpoint, we can change the data structure pointed to by R2 before the NtUserSetInformationThread call happens to exploit the vulnerability. Sadly, this is very impractical because the exploit subtracts 1 from the specified address and we need to subtract 0×80000. This is because we can’t do an unaligned access on ARM (remember, our byte’s offset is 0x19FFA6), so we need to use 0x19FFA4.
We also need the linear address at which the kernel image resides. We can find this out by calling (on the device, this can be done from a store app which will run unsigned) NtQuerySystemInformation with information class 11. If you want to know how to use NtQuerySystemInformation from a store app, read [3]. This gives us a list of all loaded drivers and their image bases, effectively bypassing ASLR in this case (although this is not what ASLR is for, it is annoying in these situations).
Exploitation

Using the remote debugger and MSFT’s armasm, I used a half-empty code page in winsrv.dll (0×10800 from the image base) to store this small payload:

push {r5-r8}
mov r7, 0x80000
ldr r8, my_addr
loc_loop_begin:
movs r3, 0xC
add r2, sp, 0x68 ;0x58 org.
add r5, r2, 4
str r8, [r5]
movs r1, 9
mvn r0, 1
mov r12, 0x10E1
svc 1
subs r7, r7, 1
cmp r7, 0
bne loc_loop_begin
pop {r5-r8}
mov r0, r0
my_addr dcd 0x12345678 the kernel's base address + 0x18

We now set a breakpoint directly after the legitimate NtUserSetInformationThread call in TerminalServerRequestThread, pressing a volume button will trigger it. This is where it gets interesting.
Redirect the instruction pointer to the payload in memory and set a breakpoint at the mov r0, r0 instruction at the end. Press F5. Now set the instruction back to the first breakpoint and remove both. Press F5 again.
Congratulations, your Windows RT device is unlocked!
Conclusion

Windows RT is a clean port of Windows 8. They are the same thing and MSFT enforces Code Integrity to artificially separate these platforms. It does not stop pirates from modifying store apps (and their license checks) because store apps are the only things that can actually run unsigned. The fact that this method works on Windows 8 as well shows how similar the systems are. You can even enforce Code Integrity on Windows 8 to see what Windows RT feels like!
The decision to ban traditional desktop applications was not a technical one, but a bad marketing decision. Windows RT needs the Win32 ecosystem to strengthen its position as a productivity tool. There are enough “consumption” tablets already.
Microsoft, please consider making code signing optional and thereby increasing the value of your Windows RT devices!
Drawbacks

Sometimes this triggers a bugcheck because we can’t control the bytes at 0x19FFA4 and 0x19FFA5 from the kernel base and they sometimes are zero, causing a 0×18 bugcheck.
This method is not practical for most users, especially because tablet buyers are less likely to know enough about computers to do this than PC users.
 

elyl

Senior Member
May 12, 2005
479
13
Glasgow
Interesting... he doesn't give any examples of code he's managed to run, though.
How do we go about building desktop software for RT since Visual Studio only targets Metro?
 

goofball2k

Senior Member
Oct 5, 2010
1,569
457
Ottawa
  • Like
Reactions: cx1

elyl

Senior Member
May 12, 2005
479
13
Glasgow

UBNAS81

Senior Member
Jul 11, 2012
81
12
Cant wait until this is ready for the masses to try out. Would there be a chance of bricking the device by doing this - I assume so.
 

GoodDayToDie

Inactive Recognized Developer
Jan 20, 2011
6,066
2,931
Seattle
There are other hacks being worked on to achieve this, or something like it, on a permanent basis (or at least without requiring an external PC). Follow the threads, we'll keep the community informed.

One request though, please: unless you have something to actually contribute, PLEASE DO NOT post on that thread! It got a bit spammed when the news broke, which is annoying to people who are using it to communicate and coordinate hacking efforts.
 

GoodDayToDie

Inactive Recognized Developer
Jan 20, 2011
6,066
2,931
Seattle
The problem is just being able to recompile it. Windows RT can actually install third-party drivers, though they need to be signed (as on x64 versions of Windows... and testsigning mode is blocked, so it has to be a trusted signature). However, if something you want isn't open-source, you're going to have a hard time getting an ARM copy of it at all, and without that you can't run in on Surface RT or any other Windows RT (ARM) device.
 

Top Liked Posts

  • There are no posts matching your filters.
  • 4
    http://surfsec.wordpress.com/2013/01/06/circumventing-windows-rts-code-integrity-mechanism/


    Circumventing Windows RT’s Code Integrity Mechanism
    January 6, 201355

    clrokr (@clrokr) – 6. Jan 2013
    It’s taken longer than expected but it has finally happened: unsigned desktop applications run on Windows RT. Ironically, a vulnerability in the Windows kernel that has existed for some time and got ported to ARM just like the rest of Windows made this possible. MSFT’s artificial incompatibility does not work because Windows RT is not in any way reduced in functionality. It’s a clean port, and a good one. But deep in the kernel, in a hashed and signed data section protected by UEFI’s Secure Boot, lies a byte that represents the minimum signing level.
    Finding the right spot

    The minimum signing level determines how good an executable’s signature is on a scale like this: Unsigned(0), Authenticode(4), Microsoft(8), Windows(12). The default value on x86 machines is of course 0 because you can run anything you like on your computer. On ARM machines, it defaults to 8.
    That means that even if you sign your apps using your Authenticode certificate, the Surface or any other Windows RT device (at this moment) will not run them. This is not a user setting, but a hardcoded global value in the kernel itself. It cannot be changed permanently on devices with UEFI’s Secure Boot enabled. It can, however, be changed in memory.
    Finding this byte in the kernel takes a while, there is no exported symbol for it and not even in the symbol database at MSFT. I found it using WinDbg and a machine running Windows 8 Pro, creating processes and watching how the system behaves when the signature checks happen all the way through CI.dll and back. Because Windows 8 and Windows RT are so similar, locating it in the ARM kernel was not hard:

    SeGetImageRequiredSigningLevel+0x18
    LDR R3, =0x59FFA6 This is our byte, 0x19FFA6 at 0x400000 image base
    LDRB R3, [R3]
    CMP R3, #4
    BHI loc_HighSigReq
    B.W loc_LowSigReq

    There are many more places where you can find this byte accessed, but none of them have an exported symbol.
    Prerequisites

    A while ago I read an article about how the Windows kernel assumes that data passed by certain processes is always well-formed [1]. This vulnerability exists in Windows RT, but exploitation is a bit harder than on Windows 8 because unsigned binaries can’t be run in the first place (and store apps don’t have the security context you need to attach to other processes). But Microsoft decided to provide something very important [2] that made this whole endeavour a lot easier. This remote debugger, when run as Administrator, can attach to the user’s CSRSS process and manipulate its memory.
    CSRSS contains a lot of calls to the vulnerable NtUserSetInformationThread function, including some that use the right parameters to exploit it. This is one of them (from winsrv.dll):

    TerminalServerRequestThread+0x230
    MOVS R3, #0xC
    ADD R2, SP, #0x58
    MOVS R1, #9
    MOV R0, 0xFFFFFFFE
    BL NtUserSetInformationThread

    A CSRSS thread executes this code. Using a breakpoint, we can change the data structure pointed to by R2 before the NtUserSetInformationThread call happens to exploit the vulnerability. Sadly, this is very impractical because the exploit subtracts 1 from the specified address and we need to subtract 0×80000. This is because we can’t do an unaligned access on ARM (remember, our byte’s offset is 0x19FFA6), so we need to use 0x19FFA4.
    We also need the linear address at which the kernel image resides. We can find this out by calling (on the device, this can be done from a store app which will run unsigned) NtQuerySystemInformation with information class 11. If you want to know how to use NtQuerySystemInformation from a store app, read [3]. This gives us a list of all loaded drivers and their image bases, effectively bypassing ASLR in this case (although this is not what ASLR is for, it is annoying in these situations).
    Exploitation

    Using the remote debugger and MSFT’s armasm, I used a half-empty code page in winsrv.dll (0×10800 from the image base) to store this small payload:

    push {r5-r8}
    mov r7, 0x80000
    ldr r8, my_addr
    loc_loop_begin:
    movs r3, 0xC
    add r2, sp, 0x68 ;0x58 org.
    add r5, r2, 4
    str r8, [r5]
    movs r1, 9
    mvn r0, 1
    mov r12, 0x10E1
    svc 1
    subs r7, r7, 1
    cmp r7, 0
    bne loc_loop_begin
    pop {r5-r8}
    mov r0, r0
    my_addr dcd 0x12345678 the kernel's base address + 0x18

    We now set a breakpoint directly after the legitimate NtUserSetInformationThread call in TerminalServerRequestThread, pressing a volume button will trigger it. This is where it gets interesting.
    Redirect the instruction pointer to the payload in memory and set a breakpoint at the mov r0, r0 instruction at the end. Press F5. Now set the instruction back to the first breakpoint and remove both. Press F5 again.
    Congratulations, your Windows RT device is unlocked!
    Conclusion

    Windows RT is a clean port of Windows 8. They are the same thing and MSFT enforces Code Integrity to artificially separate these platforms. It does not stop pirates from modifying store apps (and their license checks) because store apps are the only things that can actually run unsigned. The fact that this method works on Windows 8 as well shows how similar the systems are. You can even enforce Code Integrity on Windows 8 to see what Windows RT feels like!
    The decision to ban traditional desktop applications was not a technical one, but a bad marketing decision. Windows RT needs the Win32 ecosystem to strengthen its position as a productivity tool. There are enough “consumption” tablets already.
    Microsoft, please consider making code signing optional and thereby increasing the value of your Windows RT devices!
    Drawbacks

    Sometimes this triggers a bugcheck because we can’t control the bytes at 0x19FFA4 and 0x19FFA5 from the kernel base and they sometimes are zero, causing a 0×18 bugcheck.
    This method is not practical for most users, especially because tablet buyers are less likely to know enough about computers to do this than PC users.
    2
    I've recompiled Bochs, TightVNC (Server and Viewer), and PuTTY personally, 7zip was recompiled and posted by Cotulla, and the tablet will just run any pure .net 4.5 apps.
    2
    There are other hacks being worked on to achieve this, or something like it, on a permanent basis (or at least without requiring an external PC). Follow the threads, we'll keep the community informed.

    One request though, please: unless you have something to actually contribute, PLEASE DO NOT post on that thread! It got a bit spammed when the news broke, which is annoying to people who are using it to communicate and coordinate hacking efforts.
    1
    Interesting... he doesn't give any examples of code he's managed to run, though.
    How do we go about building desktop software for RT since Visual Studio only targets Metro?

    Someone has already run Putty on WinRT in the other thread in the Win8 forum.

    http://forum.xda-developers.com/showthread.php?goto=newpost&t=1885399

    Not sure what else has been successful