TASK 1 Modify a Dummy Read-Only File

任务要求:利用Dirty Cow 写一个只读文件

2.1 Create a Dummy File

在root文件夹中添加一个文件名为zzz,修改权限使它对其他用户只读,写入1111122223333

image-20231118152914379

当其他用户试图写入文件时,因权限不够而失败

image-20231118153430694

目标:通过Dirty Cow把”2222222“改为”*******************“

image-20231118153627419

2.2 Set Up the Memory Mapping Thread

在cow_attack.c文件中,使用MAP_PRIVATE,文件将映射到调用进程私有的内存空间。当进程试图写入文件时,内核会分配一块新的物理内存作为私有拷贝,映射的虚拟内存指向这块私有拷贝,之后的读取和写入操作都在这块私有拷贝中进行,对底层文件没有任何影响。

image-20231118153944673

为了写入底层文件,新建了两个线程madviseThread、writeThread。

2.3 Set Up the write Thread

写线程只负责写入”*******************“。其中offset是文件的偏移量,指出开始改写的位置,在这个样例中是main中传入的char * position,是通过字符串匹配找到的"2222222"的开始位置。

int f=open("/proc/self/mem", O_RDWR);

这行代码打开了一个特殊的文件/proc/self/mem,它是Linux系统中的一个虚拟文件,用于访问当前进程的内存。该文件以读写模式打开,并返回一个文件描述符f

lseek(f, offset, SEEK_SET);

这行代码使用lseek函数将文件指针f移动到偏移量为offset的位置。SEEK_SET表示从文件的开头开始计算偏移量。

然后使用write将字符串写入文件。

image-20231118155156850

2.4 The madvise Thread

madvise线程负责改变内存映射,抛弃映射内存的私有拷贝,让页表指回最初映射的内存。其中arg是在main中传入的参数(void *)file_size,是文件/zzz的大小。

image-20231118155800834

2.5 Launch the Attack

The only way for the attack to succeed is to perform the madvise() system call while the write() system call is still running. We cannot always achieve that, so we need to try many times.

如果write()和madvise()交替执行,会出现两种情况:先写入私有拷贝再指回最初映射的内存,或者先指回最初映射的内存再写(再次触发COW),这样写操作一直都在私有拷贝上进行,是不能攻击成功的。攻击成功的情况是当write()正在执行时,madvise()也执行,即当write触发COW后,页表指向私有拷贝,尚未写入时,madvise()修改页表使其指回最初映射的内存,再由write()写入。

write()和madvise()的执行顺序取决于线程的调用顺序,所以需要多次尝试。运行a.out后,按下ctrl c停止,再查看/zzz,发现已经成功修改了/zzz。攻击成功!

image-20231118161135151

image-20231118161231088

Task 2: Modify the Password File to Gain the Root Privilege

任务要求:把/etc/passwd中某一用户(以charlie为例)的UID改为0.

/etc/passwd对所有用户可读,但是只对root可写。这个文件记录了每个用户的信息,其中第三列是用户的UID。当UID=0时,用户具有root权限。

image-20231118162107654

image-20231118162001170

可以看到charlie的UID为1001.

image-20231118162535267

在cow_attack.c文件中修改以下内容:

通过字符串匹配找到charlie的UID:

image-20231118163319183

修改写入内容:

image-20231118163357737

编译并执行文件后,切换到charlie账号,发现已经是root权限的了。

image-20231118163147373

查看/etc/passwd,改动后的记录如下:改变了charlie的UID、GID和备注信息。备注信息的修改没有影响,关键是修改UID提权。为了不修改其他字段,可以注意一下content字符串长度。

image-20231118163206561

攻击成功!