[ Security ] Ch12. Race Condition

38A·2024년 10월 8일
0

컴퓨터 보안

목록 보기
11/11
post-thumbnail

Race Condition Attack

  • Happens when:
    • Multiple processes access and manipulate the same data concurrently.
    • The outcome of execution depends on a particular order.
  • If a privileged program has a race condition, the attackers may be able to affect the output of the privileged program by putting influences on the uncontrollable events.
  • When two concurrent threads of execution access a shared resource in a way that unintentionally produces different results depending on the timing of the threads or processes

Time-Of-Check To Time-Of-Use (TOCTTOU)

  • A Special Type of Race Condition
  • Occurs when checking for a condition before using a resource
    • The above program writes to a file in the /tmp directory (world-writable -> all users has permission)
    • As the root can write to any file, the program ensures that the real user has permissions to write to the target file.
    • access() system call checks if the real user id has write access to /tmp/X.
    • After the check, the file is opened for writing.
    • open() checks the effective user id which is 0 and hence file will be opened -> root 권한으로 open
  • Vulnerability
    • Goal: To write to a protected file like /etc/passwd -> root만 수정가능, 읽기는 모두가능
    • To achieve this goal we need to make /etc/passwd as our target file without changing the file name in the program.
      • Symbolic link (soft link) helps us to achieve it.
      • It is a special kind of file that points to another file
    • Issues: As the program runs billions of instructions per second, the window between the time to check and time to use lasts for a very short period of time, making it impossible to change to a symbolic link
      • If the change is too early, access() will fail.
      • If the change is little late, the program will finish using the file
    • To win the race condition (TOCTTOU window), we need to processes
      • Run vulnerable program in a loop
      • Run the attack program 위 그림 중요 !
  • Experiment Setup
  • How to Exploit Race Condition?
    • Choose a target file
      • Add the following line to /etc/passwd to add a new use
    • Launch Attack
      • Attack Process
      • Vulnerable Process
      • Two processes that race against each other: vulnerable process and attack process
    • Run the exploit

Countermeasures

Atomic Operations

  • To eliminate the window between check and use
  • These two options combined together will not open the specified file if the file already exists.
  • Guarantees the atomicity of the check and the use
  • This is just an idea, not implemented in the real system.
  • With this option, open() will only check the real user ID
  • Therefore, open() achieves check and use on it’s own and the operations are atomic.

Repeating Check and Use

  • To make it difficult to win the “race”
  • To prevent creating symbolic links
  • To enable the sticky symlink protection for world-writable sticky directories:
    • When the sticky symlink protection is enabled, symbolic links inside a sticky world-writable can only be followed when the owner of the symlink matches either the follower(Attacker) or the directory owner
  • Symlink protection allows fopen() when the owner of the symlink match either the follower (EID of the process) or the directory owner.
  • In our vulnerable program (EID is root), /tmp directory is also owned by the root, the program will not allowed to follow the symbolic link unless the link is created by the root
  • open(..., NOFOLLOW -> symbolic link X, original file만 open

Principles of Least Privilege

  • To prevent the damages after the race is won by the attacker
  • A program should not use more privilege than what is needed by the task
    • Our vulnerable program has more privileges than required while opening thefile
    • seteuid() and setuid() can be used to discard or temporarily disable privileges

Question
The least-privilege principle can be used to effectively defend against the race condition attacks discussed in this chapter. Can we use the same principle to defeat buffer-overflow attacks? Why or why not? Namely, before executing the vulnerable function, we disable the root privilege; after the vulnerable function returns, we enable the privilege back

A. No. BOF는 privilege와 관게없이 buffer, stack과 관련


Dirty COW

  • Vulnerability
    • Interesting case of the race condition vulnerability.
    • Existed in the Linux Kernel since September 2007, was discovered and attacked on October 2016
      • CVE-2016-5195
    • Affects all Linux-based operating system, including Android.
    • Consequences:
      • Modify protected files like /etc/passwd.
      • Gain root privileges by exploiting the vulnerability
    • The Dirty COW vulnerability was patched in Linux kernel versions after 4.8.3.
      To successfully execute the Dirty COW attack, Ubuntu 12.04 is required.

Memory Mapping

  • Map files or devices into memory
    • Creates a new mapping in the virtual address space of the calling process.
    • addr: Starting address for the mapped memory
    • length: Size of the mapped memory
    • prot: Desired memory protection such as execute, read, and write
    • flags: It determines whether updates to the mapping are visible (like shared memory) to other processes mapping the same region, and whether updates are carried through to the underlying file.
    • fd: File that needs to be mapped
    • offset: Offset indicating from where inside the file the mapping should start
  • Unmap files or devices
    • Deletes the mappings for the specified address range, and causes further references to addresses within the range to generate invalid memory references
    • addr: address must be a multiple of the page size (but length need not be)
    • Return Value
      • On Success: 0
      • On failure: -1 and errno is set

MAP_SHARED and MAP_PRIVATE

  • MAP_SHARED
    • The mapped memory behaves like a shared memory between the two processes.
    • When multiple processes map the same file to memory, they can map the file to different virtual memory addresses, but the physical address where the file content is held is same
  • MAP_PRIVATE
    • The file is mapped to the memory private to the calling process.
    • Changes made to memory will not be visible to other processes
    • The contents in the original memory need to be copied to the private memory.
    • If the process tries to write to the memory, OS allocates a new block of physical memory and copy the contents from the master copy to the new memory

Copy-On-Write

  • Technique that allows virtual memory in different processes to map to the same physical memory pages, if they have identical contents.
  • When a child process is created using fork() system call:
  • OS lets the child process share the parent process’s memory by making page entries point to the same physical memory.
    • If the memory is only read, memory copy is not required

Discard Copied Memory

  • Give advice about use of memory
    • Give advice or directions to the kernel about the address range beginning at address addr and with size length
    • advice: tell the kernel how it expects to use some mapped or shared memory areas, so that the kernel mcan choose appropriate read-ahead and caching techniques
      • MADV_DONTNEED: We tell the kernel that we do not need the claimed part of the address any more. The kernel will free the resource of the claimed address and the process’s page table will point back to the original physical memory
    • Return Value
      • On success: 0
      • On failure: -1 and errno is set

Mapping Read-Only Files

  • Normally, we cannot write to the read-only memory.
  • However, if the file is mapped using MAP_PRIVATE, OS makes an exception and allow us write to the mapped memory, but we have to use a different route, instead of directly using memory operations, such as memcpy().
  • The write() system call is such a route/proc/self/mem : 할당된 virtual memory에 접근할 때 이 path 사용
  • Memory is modified as we can see the changed content. But the change is only in the copy of the mapped memory; it does not change the underlying file

The Dirty-COW Vulnerability

  • For Copy-On-Write, three important steps are performed:
    • Step A: *Make a copy of the mapped memory
    • Step B: Update the page table, so the virtual memory points to newly created physical memory
    • Step C: Write to the memory
  • The above steps are not atomic in nature
    • They can be interrupted by other threads which creates a potential race condition leading to Dirty Cow vulnerability
  • If madvise() is executed between Steps B and C:
    • Step B makes the virtual memory point to 2.
    • madvise() will change it back to 1 (negating Step B)
    • Step C will modify the physical memory marked by 1, instead of the private copy.
    • Changes in the memory marked by 1 will be carried through to the underlying file, causing a read-only file to be modified.
  • When write() system call starts, it checks for the protection of the mapped memory. When it sees that is a COW memory, it triggers A,B,C without a double check

Exploiting

  • Basic Idea: Need to run two threads
    • Thread 1: write to the mapped memory using write()
    • Thread 2: discard the private copy of the mapped memory
  • We need to race these threads against each other so that they can influence the output
  • Selecting /etc/passwd as Target File
    • The file is a read-only file, so non-root users cannot modify it
    • The third field denotes the User-ID of the user (for Root, it is 0). If we can change the third field of our own record (user testcow) into 0, we can turn ourselves into root

Attack : The Main Thread

  • Set Up Memory Mapping and Threads
    • Open the /etc/passwd file in read-only mode
    • Map the memory using MAP_PRIVATE
    • Find the position in the target file.
    • Create a thread for madvise()
    • Create a thread for write()

Attack: The Two Threads

  • The write Thread
    • Replaces the string "testcow:x:1001" in the memory with "testcow:x:0000“
  • The madvise Thread
    • Discards the private copy of the mapped memory so the page table points back to the original mapped memory

Result

HGU 전산전자공학부 고윤민 교수님의 24-2 컴퓨터 보안 수업을 듣고 작성한 포스트이며, 첨부한 모든 사진은 교수님 수업 PPT의 사진 원본에 필기를 한 수정본입니다.

profile
HGU - 개인 공부 기록용 블로그

0개의 댓글