вторник, 15 ноября 2016 г.

W32pServiceTableFilter from windows 10 build 14951 x64

kd> ? nt!KeServiceDescriptorTableFilter
Evaluate expression: -8795428636992 = fffff800`2799b6c0

kd> dps fffff800`2799b6c0
fffff800`2799b6c0  fffff800`278f4450 nt!KiServiceTable
fffff800`2799b6c8  00000000`00000000
fffff800`2799b6d0  00000000`000001c4
fffff800`2799b6d8  fffff800`278f4b64 nt!KiArgumentTable
fffff800`2799b6e0  ffffa344`ba544bc0 win32k!W32pServiceTableFilter

fffff800`2799b6e8  00000000`00000000
fffff800`2799b6f0  00000000`0000049c
fffff800`2799b6f8  ffffa344`ba5462d4 win32k!W32pArgumentTableFilter

среда, 9 ноября 2016 г.

rfg longjumps

In IMAGE_LOAD_CONFIG_DIRECTORY64 there are two fields for setjmp/longjmp support - GuardLongJumpTargetTable & GuardLongJumpTargetCount. Lets see some module where this fields are not zero - for example hal.dll

воскресенье, 30 октября 2016 г.

ntstatus.idc for WDK 10.0.14931.0

added 95 new NTSTATUS values

IMAGE_LOAD_CONFIG_DIRECTORY from sdk 14951

typedef struct _IMAGE_LOAD_CONFIG_CODE_INTEGRITY {
    WORD    Flags;          // Flags to indicate if CI information is available, etc.
    WORD    Catalog;        // 0xFFFF means not available
    DWORD   CatalogOffset;
    DWORD   Reserved;       // Additional bitmask to be defined later
} IMAGE_LOAD_CONFIG_CODE_INTEGRITY, *PIMAGE_LOAD_CONFIG_CODE_INTEGRITY;

пятница, 28 октября 2016 г.

how to find nt!KeServiceDescriptorTableFilter

Unfortunately all xrefs to KeServiceDescriptorTableFilter are from non-exported functions, for example PsConvertToGuiThread:
     test    dword ptr [edi+2E8h], 18000h ; EPROCESS.Flags3
     jnz     short loc_6CAD9D

...
loc_6CAD9D:
     mov     dword ptr [esi+3Ch], offset _KeServiceDescriptorTableFilter

But we can use signatures search for part of test dword ptr [edi+2E8h], 18000h.

среда, 19 октября 2016 г.

rfg patches in windows 10 build 14942

Lets see for example body of function user32!GetCursor:
.text:00000001800026E0             GetCursor       proc near          .text:00000001800026E0 66 90                   xchg    ax, ax
.text:00000001800026E2 0F 1F 80 00 00 00 00    nop     dword ptr [rax+00000000h]
.text:00000001800026E9 B9 06 00 00 00          mov     ecx, 6
.text:00000001800026EE 48 FF 25 EB 76 09 00    jmp cs:__imp_NtUserGetThreadState
.text:00000001800026EE                         GetCursor       endp
.text:00000001800026F5 90 90 90 90 90 90 90 90                 db 8 dup(90h)


and in debugger:
0:007> ? user32!GetCursor
Evaluate expression: 140732937348832 = 00007ffe`f0bd26e0
0:007> u 00007ffe`f0bd26e0
USER32!GetCursor:
00007ffe`f0bd26e0 488b0424        mov     rax,qword ptr [rsp]
00007ffe`f0bd26e4 6448890424      mov     qword ptr fs:[rsp],rax
00007ffe`f0bd26e9 b906000000      mov     ecx,6
00007ffe`f0bd26ee 644c8b1c24      mov     r11,qword ptr fs:[rsp]
00007ffe`f0bd26f3 4c3b1c24        cmp     r11,qword ptr [rsp]
00007ffe`f0bd26f7 0f85a3e40300    jne     USER32!_guard_ss_verify_failure (00007ffe`f0c10ba0)
00007ffe`f0bd26fd 48ff25dc760900  jmp     qword ptr [USER32!_imp_NtUserGetThreadState (00007ffe`f0c69de0)]


dramatic differences ! it seems that this code has some compiler support and changes in kernel

понедельник, 10 октября 2016 г.

another cross-process scan

you can use EPROCESS.WnfContext to find list of processes. Lets see how this can be done:
kd> ? nt!ExpWnfProcessesListHead
Evaluate expression: -8781752063864 = fffff803`56c9a888
kd> dp fffff803`56c9a888
fffff803`56c9a888  fffff8a0`00125750 fffff8a0`021fb760
fffff803`56c9a898  00000000`00840082 fffff803`56a43460
fffff803`56c9a8a8  00000000`00120010 fffff803`56a43448
fffff803`56c9a8b8  00000000`00000060 00000000`00000058
fffff803`56c9a8c8  fffff803`56693df0 fffff803`56693dd8
fffff803`56c9a8d8  00000000`00760074 fffff803`56a41cd0
fffff803`56c9a8e8  00000000`00240022 fffff803`56a416c0
fffff803`56c9a8f8  00000000`00140012 fffff803`56a416a8
kd> !pool fffff8a0`00125750 2
Pool page fffff8a000125750 region is Paged pool
*fffff8a000125730 size:   f0 previous size:   90  (Allocated) *Wnf
        Pooltag Wnf  : Windows Notification Facility, Binary : nt!wnf
kd> dp fffff8a0`00125740
fffff8a0`00125740  00000000`00d80906 fffffa80`018a46c0
fffff8a0`00125750  fffff8a0`0010b9e0 fffff803`56c9a888
fffff8a0`00125760  00000000`00000000 00000000`00000000
fffff8a0`00125770  00000000`00000000 00000000`00000000
fffff8a0`00125780  fffff8a0`020c5a50 fffff8a0`00f03690
fffff8a0`00125790  00000000`00000000 fffff8a0`00129028
fffff8a0`001257a0  fffff8a0`015ee5c8 00000000`00000000
fffff8a0`001257b0  fffff8a0`001257b0 fffff8a0`001257b0
kd> !process fffffa80`018a46c0 0
PROCESS fffffa80018a46c0
    SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 00187000  ObjectTable: fffff8a000003000  HandleCount:
    Image: System

kd> dp fffff8a0`0010b9d0
fffff8a0`0010b9d0  00000000`00d80906 fffffa80`038b4940
fffff8a0`0010b9e0  fffff8a0`058ed020 fffff8a0`00125750
fffff8a0`0010b9f0  fffff8a0`00117f40 00000000`00000000
fffff8a0`0010ba00  00000000`00000000 00000000`00000000
fffff8a0`0010ba10  fffff8a0`0010ba10 fffff8a0`0010ba10
fffff8a0`0010ba20  00000000`00000000 fffff8a0`0010b938
fffff8a0`0010ba30  fffff8a0`0587f968 00000000`00000000
fffff8a0`0010ba40  fffff8a0`0010ba40 fffff8a0`0010ba40
kd> !process fffffa80`038b4940 0
PROCESS fffffa80038b4940
    SessionId: 0  Cid: 0148    Peb: 7f630624000  ParentCid: 0140
    DirBase: 10feb000  ObjectTable: fffff8a000555cc0  HandleCount:
    Image: csrss.exe


вторник, 4 октября 2016 г.

simple wnf id decoder

extern "C" int __stdcall check_id(PDWORD);
extern "C" int __stdcall get_wnf_value(PDWORD);

int _tmain(int argc, _TCHAR* argv[])
{
  if ( argc == 3 )
  {
    wchar_t *end;
    DWORD ids[2];
    ids[0] = wcstoul(argv[1], &end, 16);
    ids[1] = wcstoul(argv[2], &end, 16);
    int whut = check_id(ids);
    if ( whut )
      printf("invalid pair\n");
    else
      printf("id1 %X id2 %X index %d\n", ids[0] ^ 0xA3BC0074, ids[1] ^ 0x41C64E6D, get_wnf_value(ids) );
  }
  return 0; 
 }

the main part of code is functions check_id & get_wnf_value. I am too lazy so just ripped piece of code from ntoskrnl.exe!ExpCaptureWnfStateName function:

среда, 31 августа 2016 г.

bugs in mbedtls DH client/server

1) altough always used constant MBEDTLS_MD_SHA256 parameters are signed with sha1 and then we have MBEDTLS_ERR_RSA_VERIFY_FAILED in library\rsa.c on line 1435
2) in dh_server.c when receiving client's public value length of buffer must be dhm.len

Nice cryptolibrary, totally ready to work in kernel mode I think
patch:

вторник, 30 августа 2016 г.

how to build mbedtls-2.3.0 with wdk7

Lets say that you want to have some Diffie-Hellman-Merkle algorithm & hmac inside your driver. I found plain C library mbedtls which is very suitable for this, but has one minor problem - it does not support wdk7. So I just made port for it

вторник, 9 августа 2016 г.

ida 6.95 has been released

changelog
useful changes:
  • PE: added detection of entry point from incremental linking by Visual Studio 
  • FLIRT: added signatures for Windows Driver Kits 7-10
  • FLIRT: added detection of GsDriverEntry for Windows Drivers 
but still no support of apisetschema in PE imports, yeah

среда, 13 июля 2016 г.

FilterConnectionPorts

Under windows 10 there are some very strange objects in root directory
They are created by Filter Manager (fltmgr.sys) and is used for communication between user-mode applications and filesystem minifilters. Lets see how we can enumerate and dump this

четверг, 30 июня 2016 г.

tcpip port pools in fresh windows 10 builds

It seems that old good TcpPortPool & UdpPortPool were removed since est. build 14251 and were replaced with more complex structure stored in TcpCompartmentSet & UdpCompartmentSet

Lets see how we can get access to port pools
from InetCreatePortPool:
  push  50506E49h                       ; Tag
  push  26A8h                           ; NumberOfBytes
  mov   edi, ecx
  mov   esi, edx
  push  200h                            ; PoolType
  mov   [ebp+var_4], edi
  call  ds:__imp__ExAllocatePoolWithTag@12


some memory was alloced with tag InPP. Time for windbg

среда, 25 мая 2016 г.

KiServiceTable from w10 build 14342 x64

In healthy windows (for example w10 build 14332) KiServiceTable looks like:
.rdata:00000001402DE4C0 KiServiceTable  dq offset NtAccessCheck ; DATA XREF: KiInitializeKernel+5EF o
.rdata:00000001402DE4C8        dq offset NtWorkerFactoryWorkerReady
.rdata:00000001402DE4D0        dq offset NtAcceptConnectPort
.rdata:00000001402DE4D8        dq offset NtMapUserPhysicalPagesScatter


And in w10 build 14342 like:
.rdata:00000001402E1380 KiServiceTable  dd 0DECCCh              ; DATA XREF: KiInitializeKernel+600 o
.rdata:00000001402E1384        dd 0E44ECh
.rdata:00000001402E1388        dd 4E3470h
.rdata:00000001402E138C        db  20h
.rdata:00000001402E138D        db 0AFh ; ï
.rdata:00000001402E138E        db  64h ; d
.rdata:00000001402E138F        db    0


so I had to write a IDC script to convert this offsets to normal view:
#include <idc.idc>

static get_pe_base()
{
  auto addr, segm;
  addr = GetLongPrm(INF_MIN_EA);
  segm = SegByName("HEADER");
  if ( segm != BADADDR )
    return addr;
  return addr - 0x1000; // ditry hack
}

static main(void)
{
  auto base, cnt, addr, tab, i;
  base = get_pe_base();
  addr = LocByName("KiServiceLimit");
  if ( addr == BADADDR )
  {
    Warn("Cannot find KiServiceLimit");
    return;
  }
  cnt = Dword(addr);
  tab = LocByName("KiServiceTable");
  if ( tab == BADADDR )
  {
    Warn("Cannot find KiServiceTable");
    return;
  }
  for ( i = 0; i < cnt; i++, tab = tab + 4 )
  {
    MakeDword(tab);
    addr = Dword(tab);
    MakeComm(tab, sprintf("%x", addr + base));
    add_dref(tab, addr + base, dr_O);
  }
}

KiServiceLimit .eq. 0x1c2

четверг, 21 апреля 2016 г.

wincheck rc8.56

download
mirror

changelog:
  • add support of windows 10rtm, build 14279 & 14295
  • add dumping of g_pAuditingFuncs
  • add dumping of hal!InterruptController
  • add dumping of PICO. Sample of output:
    PspPicoProviderRoutines at FFFFF803D2F42EA0:
     DispatchSystemCall: FFFFF803B997B4B0 \SystemRoot\system32\drivers\LXCORE.SYS
     ExitThread:         FFFFF803B997B4E0 \SystemRoot\system32\drivers\LXCORE.SYS
     ExitProcess:        FFFFF803B997B450 \SystemRoot\system32\drivers\LXCORE.SYS
     DispatchException:  FFFFF803B997B1E0 \SystemRoot\system32\drivers\LXCORE.SYS
     ProcessTerminate:   FFFFF803B997B480 \SystemRoot\system32\drivers\LXCORE.SYS
     WalkUserStack:      FFFFF803B997B630 \SystemRoot\system32\drivers\LXCORE.SYS
     ProtectedRanges:    FFFFF803B9930400 \SystemRoot\system32\drivers\LXCORE.SYS
     GetAllocatedProcessImageName: FFFFF803B997B650 \SystemRoot\system32\drivers\LXCORE.SYS
  • fix wnf identifiers
  • fix WFP callouts for w8.1 & w10
  • lots of bugs were fixed

понедельник, 18 апреля 2016 г.

xxxSetAuditingInterface

Nice piece of code from lsasrv:
_GetCngAuditFunctions@4 proc near   ; CODE XREF: SrvPrepKeyIso(x)+33p
                                    ; LsapInitCNGAuditing()+Dp
  test  ecx, ecx
  jz    short loc_5095F661
  mov   dword ptr [ecx], offset _AuditFunctionTable
  xor   eax, eax
  retn

_AuditFunctionTable:
_AuditFunctionTable db    1
  db    0
  db    0
  db    0
  dd offset _CngAdtSelfTest@12              ; offset 4
  dd offset _CngAdtKeyFileOperation@32      ; offset 8
  dd offset _CngAdtKeyMigrationOperation@28 ; offset C
  dd offset _CngAdtVerificationFailure@24   ; offset 10
  dd offset _CngAdtCryptOperation@28        ; offset 14
  dd offset _CngAdtPrimitiveFailure@16      ; offset 18


This table used in SrvPrepKeyIso & LsapInitCNGAuditing functions:

понедельник, 14 марта 2016 г.

W32pServiceTable from windows 10 build 14279 64bit

W32pServiceLimit .eq. 0x47D

apisetschema.dll from windows 10 build 14279

Several new modules was added:
  • onecoreuap-print-render
  • onecoreuap-settingsync-status
  • win-core-ums
  • win-gdi-internal-uap
  • net-eap-sim
  • win-audiocore-coreaudiopolicymanager
  • win-casting-shell
  • win-com-psmregister
  • win-desktopappx
  • win-direct2d-desktop
  • win-dx-ddraw
  • win-gaming-xinput
  • win-kernelbase-packagebreakaway
  • win-media-avi
  •  win-mf-vfw
  • win-ntuser-private
  • win-rtcore-ntuser-wmpointer
  • win-security-shutdownext
  • win-uwf-servicing-apis

четверг, 3 марта 2016 г.

lxcore syscall table

I can`t get symbols for lxcore.sys so I just write simple idc scipt. Each item in table has very simple structure:
PAGE:00000001C0046620   imul  r14, r12, 38h      ; size of item in syscall table
PAGE:00000001C0046624   mov   r15, rax
PAGE:00000001C0046627   lea   rax, lx_ssdt
PAGE:00000001C004662E   add   r14, rax
PAGE:00000001C0046631   cmp   r12, 136h          ; count of items in syscall table
PAGE:00000001C0046638   jnb   loc_1C00467AE

string with name of method and arguments located at offset 0x10
IDC script to dump syscall table from lxcore.sys:
#include <idc.idc>

static main(void)
{
  auto addr, name, fp, idx, s_addr;
  fp = fopen("lx.dmp", "w");
  if ( !fp )
  {
    return;
  }
  addr = 0x1C0008110;
  for ( idx = 0; idx < 0x136; idx = idx + 1, addr = addr + 0x38 )
  {
    s_addr = Qword(addr + 0x10);
    fprintf(fp, "%X\t", idx);
    if ( s_addr != 0 )
    {
      // dump string
      for ( ; ; s_addr = s_addr + 1 )
      {
        name = Byte(s_addr);
        if ( !name )
          break;
        fprintf(fp, "%c", name);
      }
    }
    fprintf(fp, "\n");
  }
  fclose(fp);
}

And table itself

пятница, 8 января 2016 г.

CFG with LLVM

On holydays I read book "LLVM Cookbook" (not very good - lots of meaningless copy-pasted code blocks are annoying) and played a bit with fresh llvm-3.7.1 (was released 5 january)

So I decided to check whether it is possible to implement MS CFG in llvm. I have two news - good and bad, as usually

Good: yes, you can easy add instrumentation in llvm - just add some plugin for IR derived from FunctionPass and add call to your guard_check_icall before each VTBL call (or even on any ptr call). I think it will take one day for any CS-student

Bad: you need integration with MS linker and it seems that support of CFG in COFF files is totally undocumented. LLVM itself cannot make load_config and even more - their definition of coff_load_configuration in include\llvm\Object\COFF.h has no fields for CFG (like GuardCFCheckFunctionPointer and GuardCFFunctionTable)