Race_Condition_ex

时间:2021-07-17
本文章向大家介绍Race_Condition_ex,主要包括Race_Condition_ex使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

7.1. Does the following Set-UID program have a race condition vulnerability?

if (!access("/etc/passwd", W_OK)) {
    /* the real user has the write permission*/
    f = open("/tmp/X", O_WRITE);
    write_to_file(f);
}
else {
    /* the real user does not have the write permission */
    fprintf(stderr, "Permission denied\n");
}

不,/etc/passwd是一个受保护的文件,普通用户没有对它的写访问权限。所以if块永远不会被执行。

7.2. Assume we develop a new system call, called faccess(int fd, int mode), which is identical to access(), except that the file to be checked is specified by the file descriptor fd. Does the following program have a race condition problem?

int f = open("/tmp/x", O_WRITE);
if (!faccess(f, W_OK)) {
    write_to_file(f)
} else {
    close(f);
}

open 检查有效用户

access检查真实用户

/tmp/x指向目标文件 open /tmp/x 指向realuid的文件 faccess /tmp/x指向 目标文件 write_to_file

7.3. How many race conditions does attackers have to win in the following program?

int main()
{
    struct stat stat1, stat2;
    int fd1, fd2;
    if (access("/tmp/XYZ", O_RDWR)) {
        fprintf(stderr, "Permission denied\n");
        return -1;
    }
    else fd1 = open("/tmp/XYZ", O_RDWR);
    if (access("/tmp/XYZ", O_RDWR)) {
        fprintf(stderr, "Permission denied\n");
        return -1;
    }
    else fd2 = open("/tmp/XYZ", O_RDWR);
    // Check whether fd1 and fd2 have the same inode.
    fstat(fd1, &stat1);
    fstat(fd2, &stat2);
    if(stat1.st_ino == stat2.st_ino) {
        write_to_file(fd1);
    }
    else {
        fprintf(stderr, "Race condition detected\n");
        return -1;
    }
    return 0;
}

3假设所有文件名都是/tmp/XYZ,而不是tmp/XYZ,这在某些地方是不正确的。
第一个竞争是access & fd1 open之间的竞争,我们必须创建一个从/tmp/XYZ到要更改的文件的符号链接。
第二个是在 fd1 open and the second access之间,我们必须更新符号链接并将其指向用户可以访问的文件。
第三种是在the second access and fd2 open 之间,类似于第一个竞争。

7.4. In the open() system call, it first checks whether the user has the required permission to access the target file, then it actually opens the file. There seems to be a check-and-thenuse pattern. Is there a race condition problem caused by this pattern?

在open()系统调用中,检查用户权限和打开文件是一个原子操作,因此只有open()调用不可能有竞争条件。

7.5. 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.

如果问题是指在strcpy()调用之前禁用根权限,然后再启用它,那么它将不起作用,因为实际的攻击发生在我们从bof()函数返回时。如果我们在bof()调用之前禁用root权限,在调用之后启用它,那么我们就可以防止攻击。

7.6. The following root-owned Set-UID program needs to write to a file, but it wants to ensure that the file is owned by the user. It uses stat() to get the file owner’s ID, and compares it with the real user ID of the process. If they do not match, the program will exit. Please describe whether there is a race condition in the program? If so, please explain how you can exploit the race condition. The manual of stat() can be found online.

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main()
{
    struct stat statbuf;
    uid_t real_uid;
    FILE* fp;
    fp = fopen("/tmp/XYZ", "a+");
    stat("/tmp/XYZ", &statbuf);
    printf("The file owner’s user ID: %d\n", statbuf.st_uid);
    printf("The process’s real user ID: %d\n", getuid());
    // Check whether the file belongs to the user
    if (statbuf.st_uid == getuid()) {
        printf("IDs match, continue to write to the file.\n");
        // write to the file ...
        if (fp) fclose(fp);
    } else {
        printf("IDs do not match, exit.\n");
        if (fp) fclose(fp);
        return -1;
    }
    return 0;
}

使用stat()获取文件所有者的ID,并将其与进程的实际用户ID进行比较

有 /tmp/XYZ先指向realuid的文件 stat之后 指向target文件

7.7. The following root-owned Set-UID program needs to write to a file, but it wants to ensure that the file is owned by the user. It uses fstat() to get the file owner’s ID, and compares it with the real user ID of the process. If they do not match, the program will exit. Please describe whether there is a race condition in the program? If so, please explain how you can exploit the race condition. The manual of fstat() and fileno() can be found online.

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main()
{
    struct stat statbuf;
    uid_t real_uid;
    FILE* fp;
    fp = fopen("/tmp/XYZ", "a+");
    fstat(fileno(fp), &statbuf);
    printf("The file owner’s user ID: %d\n", statbuf.st_uid);
    printf("The process’s real user ID: %d\n", getuid());
    // Check whether the file belongs to the user
    if (statbuf.st_uid == getuid()) {
        printf("IDs match, continue to write to the file.\n");
        // write to the file ...
        if (fp) fclose(fp);
    } else {
        printf("IDs do not match, exit.\n");
        if (fp) fclose(fp);
        return -1;
    }
    return 0;
}

stat和lstat的区别:当文件是一个符号链接时,lstat返回的是该符号链接本身的信息;而stat返回的是该链接指向的文件的

fstat区别于另外两个系统调用的地方在于,fstat系统调用接受的是 一个“文件描述符”,而另外两个则直接接受“文件全路径”。文件描述符是需要我们用open系统调用后才能得到的,而文件全路经直接写就可以了。

fileno()函数--获取已经打开的文件的文件描述符

7.8. If we can lock a file, we can solve the race condition problem by locking a file during the check-and-use window, because no other process can use the file during the time window. Why don’t we use this approach to solve the race condition problems discussed in this chapter?

只有文件已经打开时,它才会被锁定到其他进程。在检查和打开过程中,不可能锁定文件。恶意进程可以忽略创建的任何锁。

7.9. Does the following privileged Set-UID program have a race condition problem? If so, where is the attack window? Please also describe how you would exploit this race condition window.

filename = "/tmp/XYZ";
fd = open (filename, O_RDWR);
status = access (filename, W_OK);
...
... (code omitted) ...
...
if (status == ACCESS_ALLOWED) {
    write_to_file(fd);
} else {
    fprintf(stderr, "Permission denied\n");
}

7.10. Please use the least-privilege principle to fix the race condition problem in the following program.

if (access("/tmp/XYZ", W_OK) == ACCESS_ALLOWED) {
    f = open("/tmp/XYZ", O_WRITE);
    write_to_file(f);
}
else {
    fprintf(stderr, "Permission denied\n");
}

p145

#include <stdio.h>
#include<unistd.h>

int main()
{
    uid_t real_uid = getuid(); 
    uid_t eff_uid = geteuid();
    char * fn = "/tmp/XYZ";
    char buffer[60];
    FILE *fp;
    /* get user input */
    scanf("%50s", buffer );
    seteuid(real_uid);
    if(!access(fn, W_OK)){
        fp = fopen(fn, "a+");
        fwrite("\n", sizeof(char), 1, fp);
        fwrite(buffer, sizeof(char), strlen(buffer), fp);
        fclose(fp);
    }
    else printf("No permission \n");

    seteuid(eff_uid);
}

这里报segment fault的原因是,在我们修改EID之后,事实上使用seed用户的身份去对root用户的相关内容进行操作,因为不同用户的内存空间不同,这回导致segment fault。

原文地址:https://www.cnblogs.com/tanwlanyue/p/15024036.html